问题来自 rustlings ,有问题的代码如下:
fn main() {
let mut x = 100;
let y = &mut x;
let z = &mut x;
*y += 100;
*z += 1000;
assert_eq!(x, 1200);
}
这个可以理解,因为 y, z 同时借用了 x ,2 个可变借用可能导致数据冲突。
改成如下形式可通过编译:
fn main() {
let mut x = 100;
let y = &mut x;
*y += 100;
let z = &mut x;
*z += 1000;
assert_eq!(x, 1200);
}
不理解的地方是,y 和 z 都在同一个作用域,也就是 main 函数的作用域内仍然存在 2 个可变借用,那为什么修改后的代码却编译通过了呢?
1
irytu 2022-03-02 13:21:41 +08:00 via iPhone 2
因为 y 的生命周期止于第四行 编译器是可以接受的
|
2
noe132 2022-03-02 13:22:03 +08:00 1
因为你看起来借了 2 次,实际上在任意时间只借了一次。
执行完 *y += 100; 后,编译器就知道你后面的代码不需要 y 了,所以 y 相当于不存在了。虽然你看起来 y 在整个 main 函数都还能使用,但实际上编译器想的更加细。 |
3
IsmeOvo 2022-03-02 14:01:02 +08:00 2
可以搜索关键字 Non-Lexical Lifetimes (NLL)
|
4
miyuki 2022-03-02 14:24:16 +08:00
编译器发现 y 只最多出现在第四行,后面不用了
|
5
zhs227 2022-03-02 14:26:16 +08:00 1
老版本的编译器会报错的,新版本只会检查到最后有引用的一行。也就是楼上说的 NLL 。
|
6
chuanqirenwu OP @IsmeOvo 感谢,这下理解了。
|