深入理解Rust所有权与借用

深入理解Rust所有权与借用

在 rust 中,一个变量的状态只可能是两种,一种是拥有变量的所有权,一种是拥有该变量的借用。当我们想使用变量但是又不想转移变量的所有权时我们会使用借用。有什么区别呢?如果一个变量拥有对该变量的所有权,代表可以对该变量进行任何操作,可以将旧的变量隐藏,重新声明一个可变或者不可变的变量,又或者重新转移给新的一个变量。但是借用变量不可能将一个可变变量或者不可变量重新变为其对抗的属性,也就是说,借用变量不能拥有该变量的全部控制权。

所有权

使用所有权隐藏一个旧变量,将其由一个不可变变量变为一个可变的变量。

隐藏

1
2
3
4
5
6
fn main() {
let a = String::from("abc");
let mut a = a;
a.push_str("d");
println!("{:?}", a)
}

结果:"abcd"

重新声明

使用所有权重新声明一个变量,将其由一个不可变变量变为一个可变的变量。

1
2
3
4
5
6
fn main() {
let a = String::from("abc");
let mut a = a;
a.push_str("d");
println!("{:?}", a)
}

结果:"abcd"

上面两种情况下旧的变量旧不能使用了,因为他们的所有权已经被转移,这样是为了防止一个变量被释放两次。

可变转为不可变

1
2
3
4
5
6
fn main() {
let mut a = String::from("abc");
let b = & a;
b.push_str("d");
println!("{:?}", b)
}

结果:

error[E0596]: cannot borrow `*b` as mutable, as it is behind a `&` reference
--> src/main.rs:295:5
    |
294 |     let b = & a;
    |             --- help: consider changing this to be a mutable reference: `&mut  a`
295 |     b.push_str("d");
    |     ^ `b` is a `&` reference, so the data it refers to cannot be borrowed as mutable

借用

一个owner下有多个的不可变借用的情况

rust 中的借用很像读写锁,可以同时被多个不可变变量持有借用或者只被一个可变变量借用。但是假如owner变量本身就是不可变的那么被借用后也一定是不可变的。

正确:

1
2
3
4
5
6
7
fn main() {
let a = String::from("abc");
let b = &a;
let c = &a;
println!("{:?}", b);
println!("{:?}", c);
}

结果:// "abc" // "abc"

一个owner下有多个的可变借用的情况

错误:

1
2
3
4
5
6
7
fn main() {
let mut a = String::from("abc");
let b = &mut a;
let c = &mut a;
println!("{:?}", b);
println!("{:?}", c);
}

结果:

error[E0499]: cannot borrow `a` as mutable more than once at a time
--> src/main.rs:302:13
    |
301 |     let b = &mut a;
    |             ------ first mutable borrow occurs here
302 |     let c = &mut a;
    |             ^^^^^^ second mutable borrow occurs here
303 |     println!("{:?}", b);
    |                      - first borrow later used here

一个owner下有一个的可变借用和一个不可变变借用的情况

1
2
3
4
5
6
7
fn main() {
let mut a = String::from("abc");
let b = &mut a;
let c = &a;
println!("{:?}", b);
println!("{:?}", c);
}

结果:

error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
--> src/main.rs:302:13
    |
301 |     let b = &mut a;
    |             ------ mutable borrow occurs here
302 |     let c = &a;
    |             ^^ immutable borrow occurs here
303 |     println!("{:?}", b);
    |                      - mutable borrow later used here

一个owner下有一个的可变借用

1
2
3
4
5
6
 fn main() {
let mut a = String::from("abc");
let b = &mut a;
b.push_str("d");
println!("{:?}", b)
}

结果:"abcd"

结论

rust 所有权是与借用机制可以帮助rust避免使用gc回收,通过在变量在函数作用结束时来结束变量的声明周期,通过该机制可以做到不使用gc。借用机制可以防止我们在编写多线程的时候能够避免竞态,从根源上来避免错误。

#

评论

`
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×