一个指针*和一个参考&;在Rust中,它们共享相同的表示(它们都表示一段数据的内存地址).
但是,在编写代码时,实际的区别是什么?
When porting C++ code to Rust can they be replaced safely (c++ pointer --> rust pointer, c++ reference --> rust reference ) ?
一个指针*和一个参考&;在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
(其中'a
和T
是参数).在许多情况下,生命周期 参数可以是omitted.编译器使用lifetime参数来确保引用的有效期不会超过borrow 的有效期.
指针没有生存期参数.因此,编译器无法判断特定指针是否有效.这就是为什么解引用指针被认为是unsafe
.
创建对象的共享引用时,除非对象使用某种形式的内部易变性(例如使用Cell
、RefCell
、Mutex
或RwLock
),否则该对象(即,当共享引用存在时,该对象变得不可变).然而,当你有一个指向某个对象的常量指针时,该对象在指针处于活动状态时仍然可能会改变.
当你对一个对象有一个可变的引用时,你就可以通过这个引用以独占的方式访问这个对象.任何其他访问对象的方式都会暂时禁用或无法实现.例如:
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
)的引用,然后使用&
或&mut
borrow 位置来"升级"指向引用的指针.例如:
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 迹斑斑中没有->
名操作员.
未被发送