struct MyStruct {
data: Vec<i32>,
}
impl MyStruct {
fn consume_and_reuse(self) -> Vec<i32> {
self.data
}
}
fn main() {
let mut my_struct = MyStruct { data: vec![1, 2, 3] };
let reused_data = my_struct.consume_and_reuse();
// 这里my_struct已经被移动,不能再使用,例如下面这行代码会报错:
// println!("{:?}", my_struct);
println!("Reused data: {:?}", reused_data);
}
解释
- 移动语义:在Rust中,当一个值被移动时,源变量的所有权被转移到目标变量。在
MyStruct
的consume_and_reuse
方法中,self
是按值传递的,这意味着MyStruct
实例的所有权被转移到方法内部。方法返回self.data
,data
的所有权被移动出MyStruct
实例并返回给调用者。
- 编译器保证内存安全:
- 所有权系统:Rust的所有权系统确保每个值有且只有一个所有者。当
my_struct
调用consume_and_reuse
方法时,my_struct
失去对data
的所有权,因此后续不能再使用my_struct
。如果尝试使用已被移动的my_struct
,编译器会报错,从而防止悬空指针和数据竞争。
- 内存释放:当
MyStruct
实例的所有权被转移时,Rust的所有权系统会确保在MyStruct
实例离开作用域时,其占用的内存(包括Vec<i32>
占用的内存)会被正确释放。由于Vec<i32>
实现了Drop
trait,当Vec<i32>
的所有权被转移或者离开作用域时,其内部的内存会被自动释放,保证了内存安全。