类型
从 C++ 视角看,rust 只有两种类型,资源句柄和非资源句柄,区别在于非资源句柄实现了 Copy Trait。资源句柄分为没有引用计数的资源句柄和有引用计数的资源句柄(即智能指针)。
从 C++ 的角度来看,rust 中所有权保证了同一时间堆上分配出去的内存有且只有被一个没有引用计数的资源句柄持有,或者被智能指针的多个拷贝持有,通过这个做法,保证从堆上分配出去的内存都有资源句柄进行管理并且不存在二次释放,资源句柄作用域结束自动释放内存确保内存不会泄露(不存在野指针)。
实现 Copy Trait 的类型被 rust 要求不能实现 Drop Trait,对应的也就是不能管理从堆上分配的内存(保证不是资源句柄),这种类型以基础类型为代表,长度可以在编译时确定,并自动在栈上分配变量的内存。
所有权的移动
所有权的移动实际上是旧的资源句柄被浅拷贝到新的资源句柄,旧资源句柄被清空,资源句柄的拷贝都只与栈上的变量有关。
有一种情况所有权的移动不会导致拷贝:
type array = [u32; 32];
fn move_from_callee() -> array {
let mut v : array = [0; 32];
println!("move from callee {:p}", &v);
v
}
fn main() {
let v1 = move_from_callee();
println!("move_from_callee {:p}", &v1);
}
所有权从move_from_callee转移到 main 函数中,这里 rust 优化使得 v 与 v1 地址相同,都在 main 的函数栈帧中。
引用
引用是指向栈上变量的指针,是一种独立的类型,用于便于访问和修改资源句柄中的数据(当然也可以是非资源句柄),同时不会破坏关于资源句柄约定。