Rust 中的多重可变引用预防是如何工作的?

How does multiple mutable reference prevention work in Rust?

为什么允许这样做:

fn main() {
    let mut w = MyStruct;
    w.fun1();
}

struct MyStruct;

impl MyStruct {
    fn fun1(&mut self) {
        self.fun2();
    }

    fn fun2(&mut self) {
        println!("Hello world 2");
    }
}

在上面的代码中,fun1() 获取 mut MyStruct 并使用 mut MyStruct 调用 fun2()。它是一个范围内的双可变引用吗?

这是允许的,因为借用检查器可以断定在执行期间只有一个可变引用被访问。虽然 fun2 是 运行,但 fun1 中没有其他语句正在执行。当 fun1 中的下一条语句(如果有的话)开始执行时,fun2 已经删除了它的可变引用。

在链接的其他问题中:

fn main() {
    let mut x1 = String::from("hello");
    let r1 = &mut x1;
    let r2 = &mut x1;

    r1.insert(0, 'w');
}

我们可以说 r2 从未被使用过,但借用检查员决定它不应该被允许。考虑这个例子:

fn main() {
    let mut x1 = String::from("hello");
    let r1 = &mut x1;
    r1.insert(0, 'w');

    let r2 = &mut x1;
    r2.insert(0, 'x');
}

这可以正确编译和运行。我想借用检查器假定生命周期 r1 在创建 r2 之前结束。如果这是有道理的,那么调用改变 self 的方法就不会那么令人惊讶了。

(我不知道为什么第一段代码不能编译,但我很高兴 Rust 团队这样做了。r2 无论如何都不应该存在。)