V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
chuanqirenwu
V2EX  ›  Rust

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

  •  
  •   chuanqirenwu · 2022-03-02 12:56:25 +08:00 · 1226 次点击
    这是一个创建于 999 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    6 条回复    2022-03-02 20:22:59 +08:00
    irytu
        1
    irytu  
       2022-03-02 13:21:41 +08:00 via iPhone   ❤️ 2
    因为 y 的生命周期止于第四行 编译器是可以接受的
    noe132
        2
    noe132  
       2022-03-02 13:22:03 +08:00   ❤️ 1
    因为你看起来借了 2 次,实际上在任意时间只借了一次。
    执行完 *y += 100; 后,编译器就知道你后面的代码不需要 y 了,所以 y 相当于不存在了。虽然你看起来 y 在整个 main 函数都还能使用,但实际上编译器想的更加细。
    IsmeOvo
        3
    IsmeOvo  
       2022-03-02 14:01:02 +08:00   ❤️ 2
    可以搜索关键字 Non-Lexical Lifetimes (NLL)
    miyuki
        4
    miyuki  
       2022-03-02 14:24:16 +08:00
    编译器发现 y 只最多出现在第四行,后面不用了
    zhs227
        5
    zhs227  
       2022-03-02 14:26:16 +08:00   ❤️ 1
    老版本的编译器会报错的,新版本只会检查到最后有引用的一行。也就是楼上说的 NLL 。
    chuanqirenwu
        6
    chuanqirenwu  
    OP
       2022-03-02 20:22:59 +08:00
    @IsmeOvo 感谢,这下理解了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1528 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 17:06 · PVG 01:06 · LAX 09:06 · JFK 12:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.