一个指针*和一个参考&在Rust中,它们共享相同的表示(它们都表示一段数据的内存地址).

但是,在编写代码时,实际的区别是什么?

When porting C++ code to Rust can they be replaced safely (c++ pointer --> rust pointer, c++ reference --> rust reference ) ?

推荐答案

尽可能使用引用,必要时使用指针.如果您没有执行FFI或超出编译器可验证范围的内存管理,则不需要使用指针.

引用和指针都有两种变体.有共享引用&和可变引用&mut.有常量指针*const和mut指针*mut(它们映射到C中的常量和非常量指针).然而,引用的语义与指针的语义完全不同.

引用在类型和生命周期内都是泛型的.共享引用以长格式写入&'a T(其中'aT是参数).在许多情况下,生命周期 参数可以是omitted.编译器使用lifetime参数来确保引用的有效期不会超过borrow 的有效期.

指针没有生存期参数.因此,编译器无法判断特定指针是否有效.这就是为什么解引用指针被认为是unsafe.

创建对象的共享引用时,除非对象使用某种形式的内部易变性(例如使用CellRefCellMutexRwLock),否则该对象(即,当共享引用存在时,该对象变得不可变).然而,当你有一个指向某个对象的常量指针时,该对象在指针处于活动状态时仍然可能会改变.

当你对一个对象有一个可变的引用时,你就可以通过这个引用以独占的方式访问这个对象.任何其他访问对象的方式都会暂时禁用或无法实现.例如:

let mut x = 0;
{
    let y = &mut x;
    let z = &mut x; // ERROR: x is already borrowed mutably
    *y = 1; // OK
    x = 2; // ERROR: x is borrowed
}
x = 3; // OK, y went out of scope

Mut指针没有这样的保证.

引用不能为空(非常类似C++引用).指针可以为空.

指针可以包含任何适合usize的数值.初始化指针不是unsafe;只是取消了对它的引用.另一方面,即使从未取消引用,生成无效引用也被视为undefined behavior.

如果你有一个*const T,你可以使用as自由地将其转换为*const U*mut T.你不能在推荐信上这么做.但是,您可以使用as来强制转换对指针的引用,也可以通过取消对指针(同样是unsafe)的引用,然后使用&&mutborrow 位置来"升级"指向引用的指针.例如:

use std::ffi::OsStr;
use std::path::Path;

pub fn os_str_to_path(s: &OsStr) -> &Path {
    unsafe { &*(s as *const OsStr as *const Path) }
}

在C++中,引用是"自动go 引用指针".在Rust中,通常仍然需要显式地取消引用.例外情况是当您使用.运算符时:如果左侧是引用,编译器将自动取消引用它(如有必要,递归地!).然而,指针不会自动取消引用.这意味着,如果要取消引用并访问字段或方法,则需要写入(*pointer).field(*pointer).method(). rust 迹斑斑中没有->名操作员.

Rust相关问答推荐

为什么我的梅森素数代码的指数越大,速度就越快?

borrow 和内部IntoIterator

为什么std repeat trait绑定在impl块和关联函数之间?

通过不同的字段进行散列和排序的 struct (需要不同的EQ实现)

不能在一个代码分支中具有不变的自身borrow ,而在另一个代码分支中具有可变的self borrow

有没有可能让泛型Rust T总是堆分配的?

定义只有一些字段可以缺省的 struct

如何获取光标下的像素 colored颜色 ?

为什么在 Allocator API 中 allocate() 使用 `[u8]` 而 deallocate 使用 `u8` ?

std mpsc 发送者通道在闭包中使用时关闭

为什么我可以使用 &mut (**ref) 创建两个实时 &mut 到同一个变量?

为什么 `tokio::join!` 宏不需要 Rust 中的 `await` 关键字?

如何使返回 XMLError 的方法与 anyhow::Error 兼容?

Rust 异步和 AsRef 未被发送

使用 HashMap 条目时如何避免字符串键的短暂克隆?

在单独的线程上运行 actix web 服务器

将文件的第一行分别读取到文件的其余部分的最有效方法是什么?

有没有办法阻止 rust-analyzer 使非活动代码变暗?

如何在宏中的多个参数上编写嵌套循环?

为什么 Rust 中的关联类型需要明确的生命周期注释?