为什么Rust中不允许嵌套的不可变借用



考虑到非词法生存期是如何工作的,我不明白为什么编译器不允许以下内容:

fn main() {
let mut x = 10;
let y = &mut x;
let z = &x; // Immutable reference scope starts and ends here.
println!("{}", y);
}

我知道嵌套(我所说的"嵌套"是指范围的开始和结束都没有调用以前定义的引用(可变引用可能会使以前定义的参考失效。然而,我不清楚为什么不可变引用不能嵌套。

下面的评论回应道:

因此分析仍然是本地的。当一个可变的借项很突出时,你不能创建一个对一个事物的不可变引用。这是一个很容易检查的简单规则。

我回答了为什么这个答案对我来说不满意,因为rust编译器执行的检查比这个更高级。

fn main() {
let mut x = 10;
let y = &mut x;
println!("{}", x); // error: immutable borrow occurs here
println!("{}", y);
}

对我来说,也许是天真的,这表明了一种足够复杂的能力,足以识别我上面描述的特殊情况,因为编译器已经在跟踪借用事件。

问题的进一步澄清:

如果一个不可变借用的范围在一个可变借用范围内开始和结束,而没有任何额外的中间借用,那么有没有一个具体的例子可以说明为什么这会被认为是不安全的?如果这是可证明的安全的,那么编译器不允许这样做有什么原因吗?

Rust的工作不是弄清楚引用的使用位置,因为这会给类型系统带来太多负担,使其无法使用。因此,Rust无法判断不可变引用是否被发送到另一个线程,该线程当前正在写入该值,而您正在使用不可变引用读取该值。

最新更新