此问题和代码改编自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');
}
答案 0 :(得分:3)
一次只允许您对一个值进行单个可变引用。当您可变地重新借用作为参数时,对于编译器来说,琐碎很容易,因为您不会再使用ref_string
,因此代码是安全的。
我的心理形象是,变异性存在“监管链”。 ref_string
是持有者,可以暂时将其放弃给&mut *ref_string
创建的临时对象。如果超出范围,则将可变性返回给它。好像代码是:
{
let x = &mut *ref_string;
test(x);
}
但是,当您尝试“四处走动”并获得可变的参考时,您将忽略监管链。编译器会阻止您,因为它不能轻而易举地看到它是安全的。
值得注意的是non-lexical lifetimes改善了原始情况。启用基于MIR的借阅检查器后,编译器可以看到ref_string
的第二次调用发生时test
不再使用,因此将独占访问安全地转移到那里