所有权和移动
由于变量负责释放它们自己的资源,资源只能有一个所有者。这可以防止资源被多次释放。请注意,并非所有变量都拥有资源(例如引用)。
当进行赋值(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 ^ 尝试取消此行注释 }