当前位置:   article > 正文

Rust语言Ownership,Reference和Lifetime详解_rust ownership lifetime

rust ownership lifetime

1. Ownership

rust的ownership系统是它区别与其它语言的最主要的特征。只有理解了ownership系统,才能真正算是入门。

Rust的绑定变量有一个属性:获得它所绑定资源的所有权。这意味着当绑定变量超出作用域时,它所绑定资源的资源就会释放。

fn foo() {
    let v = vec![1, 2, 3];
}
  • 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]);   //使用原来的那个绑定变量。
  • 1
  • 2
  • 3
  • 4
  • 5

运行上面的代码会报错。

error: use of moved value: `v`
println!("v[0] is: {
   }", v[0]);
  • 1
  • 2
  • 3
let v2= v;
  • 1

这行代码是把v赋给v2,它们都指向同一个vector,这违反了Rust安全承诺。所以在这个赋值后Rust不允许再使用变量v。在编译器优化时,可以会把它释放掉。看起来就像v的所有都转移(move)到v2了。

下面我们再看一个例子,这回我们把类型从vector换成i32.

let v  = 1;

let v2 = v;

println!("v is: {}", v);
  • 1
  • 2
  • 3
  • 4
  • 5

这个代码就可以运行,为什么?因为这个例子里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;
  • 1
  • 2
  • 3

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];

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/223734
推荐阅读
相关标签
  

闽ICP备14008679号