所有权和移动
由于变量负责释放它们自己的资源,资源只能有一个所有者。这可以防止资源被多次释放。请注意,并非所有变量都拥有资源(例如引用)。
当进行赋值(let x = y)或按值传递函数参数(foo(x))时,资源的所有权会被转移。在 Rust 中,这被称为移动(move)。
资源移动后,原所有者将无法再被使用。这避免了悬垂指针的产生。
// 此函数获取堆分配内存的所有权
fn destroy_box(c: Box<i32>) {
println!("正在销毁一个包含 {} 的 box", c);
// `c` 被销毁,内存被释放
}
fn main() {
// **栈**分配的整数
let x = 5u32;
// 将 `x` **复制**到 `y` - 没有资源被移动
let y = x;
// 两个值可以独立使用
println!("x 是 {},y 是 {}", x, y);
// `a` 是指向**堆**分配整数的指针
let a = Box::new(5i32);
println!("a 包含:{}", a);
// 将 `a` **移动**到 `b`
let b = a;
// `a` 的指针地址(而非数据)被复制到 `b`
// 现在两者都指向同一块堆分配的数据
// 但 `b` 现在拥有它
// 错误!`a` 不再拥有堆内存,因此无法访问数据
//println!("a 包含:{}", a);
// TODO ^ 尝试取消此行注释
// 此函数从 `b` 获取堆分配内存的所有权
destroy_box(b);
// 此时堆内存已被释放,这个操作会导致解引用已释放的内存
// 但编译器禁止这样做
// 错误!原因与前面的错误相同
//println!("b 包含:{}", b);
// TODO ^ 尝试取消此行注释
}