为什么重新借用仅适用于取消引用的指针?

时间:2018-06-25 02:14:26

标签: rust borrowing

此问题和代码改编自Why does creating a mutable reference to a dereferenced mutable reference work?。那里的答案解释了重新借款,但没有解释围绕它的约定的原因。

下面对test的两次调用似乎是等效的,为什么只有第一个有效?

fn main() {
    let mut string = String::new();
    let ref_string = &mut string;

    // Compiles
    test(&mut *ref_string);

    // Doesn't compile
    test(&mut string);
}

fn test(s: &mut String) {
    s.push('t');
}

1 个答案:

答案 0 :(得分:3)

一次只允许您对一个值进行单个可变引用。当您可变地重新借用作为参数时,对于编译器来说,琐碎很容易,因为您不会再使用ref_string,因此代码是安全的。

我的心理形象是,变异性存在“监管链”。 ref_string是持有者,可以暂时将其放弃给&mut *ref_string创建的临时对象。如果超出范围,则将可变性返回给它。好像代码是:

{
    let x = &mut *ref_string;
    test(x);
}

但是,当您尝试“四处走动”并获得可变的参考时,您将忽略监管链。编译器会阻止您,因为它不能轻而易举地看到它是安全的。


值得注意的是non-lexical lifetimes改善了原始情况。启用基于MIR的借阅检查器后,编译器可以看到ref_string的第二次调用发生时test不再使用,因此将独占访问安全地转移到那里