1

这个问题和代码改编自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');
}
4

1 回答 1

4

您一次只能有一个对值的可变引用。当您可变地重新借用作为参数时,编译器很容易看到您不会同时使用ref_string,因此代码是安全的。

我的心理印象是可变性有一个“监管链”。ref_string是持有者,可以暂时将其交给由&mut *ref_string. 当超出范围时,可变性返回给它。就好像代码是:

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

但是,当您尝试“四处走动”并获取可变引用时,您忽略了监管链。编译器会阻止您,因为它无法轻易看出它是安全的。


值得注意的是,非词汇生命周期改善了原始情况。当启用基于 MIR 的借用检查器时,编译器可以看到ref_string在第二次调用发生时不再使用test它,因此将独占访问权转移到那里是安全的。

于 2018-06-25T03:00:39.100 回答