赞
踩
rust的ownership系统是它区别与其它语言的最主要的特征。只有理解了ownership系统,才能真正算是入门。
Rust的绑定变量有一个属性:获得它所绑定资源的所有权。这意味着当绑定变量超出作用域时,它所绑定资源的资源就会释放。
fn foo() {
let v = vec![1, 2, 3];
}
绑定变量v的作用域是函数foo的函数体,创建v时,先会在栈上分配空间来保存v这个变量 ,然后会在堆上分配空间以保存它的3个元素。当v超出作用域时,Rust会清除栈和堆上这些资源。
有一点要注意:Rust确保有且只有一个变量绑定到给定的资源。
let v = vec![1, 2, 3]; //创建一个vector,并绑定到一个变量
let v2 = v; //把它赋给另一个变量。
println!("v[0] is: {}", v[0]); //使用原来的那个绑定变量。
运行上面的代码会报错。
error: use of moved value: `v`
println!("v[0] is: {
}", v[0]);
let v2= v;
这行代码是把v赋给v2,它们都指向同一个vector,这违反了Rust安全承诺。所以在这个赋值后Rust不允许再使用变量v。在编译器优化时,可以会把它释放掉。看起来就像v的所有都转移(move)到v2了。
下面我们再看一个例子,这回我们把类型从vector换成i32.
let v = 1;
let v2 = v;
println!("v is: {}", v);
这个代码就可以运行,为什么?因为这个例子里v的类型是i32,它实现了Copy
trait,所以let v2 = v;
这行代码执行时,rust会把v的值深度copy一份,然后给v2,所以v在赋值后可以用的。
v2和v拥有不同的资源,分别是各自资源的owner。
move还是copy ?
当一个局部变量用做右值时,它可能会被move或copy,取决于它的类型,如果它实现了Copy
这个trait,那它就会被copied,否则就会被moved.
let v = vec![1, 2, 3];
let v2 = v;
vector没有实现Copy
trait,所以在赋值后v
就不可以用了。
如果我们写了一个函数,以vector为参数,为了能让函数调用后原来的变量能正常使用,我们必须手动归还这个ownership。
fn foo(v1: Vec<i32>, v2: Vec<i32>) -> (Vec<i32>, Vec<i32>, i32) {
// do stuff with v1 and v2
// hand back ownership, and the result of our function
(v1, v2, 42)
}
let v1 = vec![1, 2, 3];
let v2 = vec![1, 2, 3];
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。