Rust中的指针*和引用&共享相同的表示形式(它们都表示一条数据的内存地址)。
编写代码时,实际的区别是什么?
将C ++代码移植到Rust时,是否可以安全地替换它们(c ++指针-> rust指针,c ++参考-> rust参考)?
可以使用引用,而必须使用指针。如果您不执行FFI或内存管理,而编译器无法验证,则不需要使用指针。
引用和指针都有两种变体。有共享引用&
和可变引用&mut
。有const指针*const
和mut指针*mut
(它们映射到C语言中的const和非const指针)。但是,引用的语义与指针的语义完全不同。
引用在类型和生命周期内都是通用的。共享引用&'a T
以长格式编写(其中'a
和T
是参数)。生命周期参数在许多情况下可以省略。生命周期参数由编译器用来确保引用的生存期不超过借用有效期。
指针没有生存期参数。因此,编译器无法检查特定的指针是否有效。这就是为什么要取消引用指针的原因unsafe
。
当创建一个共享的参照对象,即冻结对象(即对象而共享参考存在变得不可变的),除非对象使用某种形式的内部的可变性(例如,使用Cell
,RefCell
,Mutex
或RwLock
)。但是,当您有一个指向对象的const指针时,在该指针处于活动状态时,该对象仍可能会更改。
当您对一个对象有可变的引用时,可以保证通过此引用可以独占访问该对象。暂时禁用任何其他访问对象的方法,或者无法实现。例如:
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指针没有这样的保证。
引用不能为null(非常类似于C ++引用)。指针可以为空。
指针可以包含任何可能适合的数值usize
。初始化指针不是unsafe
; 只是取消引用它。
如果有*const T
,则可以将其自由转换为a*const U
或*mut T
using as
。您不能通过引用来做到这一点。但是,您可以使用as
,将引用强制转换为指针,也可以通过取消引用指针(再次是unsafe
),然后使用&
或借用该位置,来将指针“升级”至引用&mut
。例如:
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 ++中,引用是“自动取消引用的指针”。在Rust中,您经常仍然需要显式地取消引用。例外是使用.
运算符时:如果左侧是引用,则编译器将自动对其取消引用(必要时递归!)。但是,指针不会自动取消引用。这意味着如果要取消引用并访问字段或方法,则需要编写(*pointer).field
或(*pointer).method()
。->
Rust中没有运算符。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句