请教一个 borrow as mutable more than once 的问题。

2022-03-02 12:56:25 +08:00
 chuanqirenwu

问题来自 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 个可变借用,那为什么修改后的代码却编译通过了呢?

1256 次点击
所在节点    Rust
6 条回复
irytu
2022-03-02 13:21:41 +08:00
因为 y 的生命周期止于第四行 编译器是可以接受的
noe132
2022-03-02 13:22:03 +08:00
因为你看起来借了 2 次,实际上在任意时间只借了一次。
执行完 *y += 100; 后,编译器就知道你后面的代码不需要 y 了,所以 y 相当于不存在了。虽然你看起来 y 在整个 main 函数都还能使用,但实际上编译器想的更加细。
IsmeOvo
2022-03-02 14:01:02 +08:00
可以搜索关键字 Non-Lexical Lifetimes (NLL)
miyuki
2022-03-02 14:24:16 +08:00
编译器发现 y 只最多出现在第四行,后面不用了
zhs227
2022-03-02 14:26:16 +08:00
老版本的编译器会报错的,新版本只会检查到最后有引用的一行。也就是楼上说的 NLL 。
chuanqirenwu
2022-03-02 20:22:59 +08:00
@IsmeOvo 感谢,这下理解了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/837400

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX