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

时间:2021-05-22 22:28:56

标签: rust borrow-checker

鉴于非词法生命周期的工作方式,我不明白为什么编译器不允许以下内容:

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);
}

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

问题更清楚:

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

1 个答案:

答案 0 :(得分:1)

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

相关问题