问题描述
fn main() {
let mut x = 5;
let y = &mut x;
println!("{}", x);
println!("{}", y);
}
使用 https://play.rust-lang.org/ 编译报错:
Compiling playground v0.0.1 (/playground)
error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
--> src/main.rs:4:20
|
3 | let y = &mut x;
| ------ mutable borrow occurs here
4 | println!("{}", x);
| ^ immutable borrow occurs here
5 | println!("{}", y);
| - mutable borrow later used here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0502`.
error: could not compile `playground`
To learn more, run the command again with --verbose.
但是 把输出代码调换一下顺序,就可以编译通过了
fn main() {
let mut x = 5;
let y = &mut x;
println!("{}", y);
println!("{}", x);
}
输出:
Compiling playground v0.0.1 (/playground)
Finished dev [unoptimized + debuginfo] target(s) in 0.84s
Running `target/debug/playground`
Standard Output
5
5
网友的解答
网友:freedom967
你的写法实际上违背了借用规则,x被可变借出后,在当前作用域下,你是不能再访问x的,因为这个违背了可变借用和不可变不能同时存在的原则,没错,x被借出后,原则上你是不能再访问x的。。。为什么调换顺序后可以,那是rust编译器的锅,因为他判断y在后面不再被使用(也就是可变借用到这里结束了),所以这时候你访问x是可以的,非词法作用域的功劳,简化了实际代码编写的。谨记rust的借用规则才是重点。
网友:catsalwaysmeow
不清楚这个资料有没有过时,可以参考一下:https://github.com/rust-lang/rfcs/blob/master/text/2094-nll.md
借用的生命周期是囊括了这个借用被使用的每一个时间点的最小范围。第一份代码中,打印x时,可变借用y仍然存活(因为之后还要打印y),那么x仍处于被借用中的冻结状态,所以报错了。第二份代码中,打印x时,y的生命周期已经结束了,因为它是一个借用。
另外一位网友:eric642的解释:
fn main() {
let mut x = 5; -----------x的生命周期
let y = &mut x; =====y的生命周期
println!("{}", y); =====>end
println!("{}", x); -------->end
}
fn main() {
let mut x = 5; -----------x的生命周期
let y = &mut x; =====y的生命周期
println!("{}", x); -------->end
println!("{}", y); =====>end
}
引用的生命周期不能小于被引用的.
原文地址:https://rustcc.cn/article?id=1939f5db-6a18-4617-8c87-417447698fad