cargo new borrowing && mov borrowing 05-borrowing && cd 05-borrowing
src/main.rs
1 2 3 4 5
fnmain() { let a = vec![1,2,3]; let b = a; println!("{:?} {:?}", a, b); }
结果报错如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
$ cargo run error[E0382]: borrow of moved value: `a` --> src/main.rs:4:27 | 2 | let a = vec![1,2,3]; | - move occurs because `a` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait 3 | let b = a; | - value moved here 4 | println!("{:?} {:?}", a, b); | ^ value borrowed here after move
error: aborting due to previous error
For more information about this error, try `rustc --explain E0382`. error: could not compile `borrowing`.
To learn more, run the command again with --verbose.
那么我们将代码改成下面: src/main.rs
1 2 3 4 5 6
fnmain() { let a = vec![1,2,3]; // let b = a; Error; value borrowed here after move let b = &a; // 正确:增加&符号 println!("{:?} {:?}", a, b); }
借用概念适用于复制类型(Copy type )和移动类型( Move type )。 src/main.rs
1 2 3 4 5
fnmain() { let a = vec![1,2,3]; let b = &a; // 这里是共享借用 Shared Borrowing (&T) println!("{:?} {:?}", a, b); // a 能正确访问到原来的数据 [1, 2, 3] [1, 2, 3] }
src/main.rs
1 2 3 4 5
fnmain() { letmut a = vec![1,2,3]; let b = &mut a; // 这里是可变借用 Mutable Borrowing (&mut T) println!("{:?} {:?}", a, b); // a trying to access `a` as a shared borrow, so giving an error }
error[E0596]: cannot borrow `a` as mutable, as it is not declared as mutable --> src/main.rs:3:13 | 2 | let mut a = vec![1,2,3]; | - help: consider changing this to be mutable: `mut a` 3 | let b = &mut a; | ^^^^^^ cannot borrow as mutable
error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable --> src/main.rs:4:27 | 3 | let b = &mut a; | ------ mutable borrow occurs here 4 | println!("{:?} {:?}", a, b); | ^ - mutable borrow later used here | | | immutable borrow occurs here
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0502, E0596. For more information about an error, try `rustc --explain E0502`. error: could not compile `borrowing`.
To learn more, run the command again with --verbose.
可变借用,已经将所有权让给了b,那么a就不能再访问原来的数据。
要是还需要a继续可访问呢?
1 2 3 4 5 6 7 8 9
fnmain() { letmut a = vec![1,2,3]; // 增加一个括号,借用的生命周期,结束在括号范围内 { let b = &mut a; // &mut borrow of `a` starts here // any other code // 大括号结束后,b会把所有权还给a } println!("{:?}", a); // [1, 2, 3] }
接着看函数的传递参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
fnmain() { letmut a = vec![1,2,3]; { let b = &mut a; // &mut borrow of `a` starts here println!("b = {:?}", b); } println!("a = {:?}", a);
let c = get_fisrt_element(&a); println!("c = {:?}", c); }
fnget_fisrt_element(a: &Vec<i32>) -> i32 { a[0] }
1 2 3 4 5
$ cargo run …… b = [1, 2, 3] a = [1, 2, 3] c = 1
要是函数内部需要修改数组a的值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
fnmain() { letmut a = vec![1,2,3]; { let b = &mut a; // &mut borrow of `a` starts here println!("b = {:?}", b); } println!("a = {:?}", a);
let c = get_fisrt_element(&a); println!("c = {:?}", c); }
error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference --> src/main.rs:14:5 | 13 | fn get_fisrt_element(a: &Vec<i32>) -> i32 { | --------- help: consider changing this to be a mutable reference: `&mut std::vec::Vec<i32>` 14 | a[2] = 9; | ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0596`. error: could not compile `borrowing`.
To learn more, run the command again with --verbose.
共享借用是不能修改传参的值,若需要修改传参的值,需要用可变借用 &mut
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
fnmain() { letmut a = vec![1,2,3]; { let b = &mut a; // &mut borrow of `a` starts here println!("b = {:?}", b); } println!("a = {:?}", a); // 打印a的值
let c = get_fisrt_element(&mut a); println!("c = {:?}", c); println!("a = {:?}", a); // 再次打印a的值 }