为什么Rust阻止了多个可变引用?

麦克程序员

像本主题一样,Rust为什么阻止多个可变引用?我已经阅读了rust-book中的章节,并且我了解到,当我们拥有多线程代码时,我们就可以避免数据竞争,但让我们看一下以下代码:

fn main() {
    let mut x1 = String::from("hello");
    let r1 = &mut x1;
    let r2 = &mut x1;

    r1.insert(0, 'w');

}

该代码不会同时运行,因此不会发生数据争用。当我创建新线程并且要在新线程中使用父线程中的变量时,还需要移动它,因此只有新线程才是父变量的所有者。

我看到的唯一原因是,程序员在成长过程中可能会迷失自己的代码。我们在多个地方可以修改一个数据,即使代码没有并行运行,我们也会遇到一些错误。

麦卡顿

Rust会同时阻止两个可变引用以防止数据争用这一事实是一个普遍的误解。这只是原因之一。防止使用两个可变的引用,可以轻松地在类型上保留不变式,并使编译器强制执行不变式。

以下面的C ++代码示例为例:

#include <vector>

int main() {
    std::vector<int> foo = { 1, 2, 3 };

    for (auto& e: foo) {
        if (e % 2 == 0) {
            foo.push_back(e+1);
        }
    }

    return 0;
}

这是不安全的,因为在迭代时无法对向量进行突变。修改向量可能会重新分配其内部缓冲区,这会使所有引用无效。在C ++中,这是一个UB。在Python,Java或C#(可能还有大多数其他语言)中,您将获得运行时异常。

但是,Rust可以在编译时防止此类问题:

fn main() {
    let mut foo = vec![1, 2, 3];

    for e in foo {
        if e % 2 == 0 {
            foo.push(e+1);
        }
    }
}

给出一个错误:

error[E0382]: borrow of moved value: `foo`
 --> src/main.rs:6:13
  |
2 |     let mut foo = vec![1, 2, 3];
  |         ------- move occurs because `foo` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
3 |     
4 |     for e in foo {
  |              ---
  |              |
  |              value moved here
  |              help: consider borrowing to avoid moving into the for loop: `&foo`
5 |         if e % 2 == 0 {
6 |             foo.push(e+1);
  |             ^^^ value borrowed here after move

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

假设两个可变引用都不能别名,Rust编译器为什么不优化代码?

如何使Rust可变引用不可变?

为什么在可变引用上调用方法涉及“借用”?

关于可变内部引用的Rust借用规则是什么?

为什么创建对取消引用的可变引用的可变引用有效?

为什么Rust不允许可变别名?

当返回对范围外的值的可变引用的不可变引用时,为什么在范围结束时丢弃了可变引用?

为什么通过原始指针修改可变引用的值不会违反Rust的别名规则?

为什么在同一范围内可能有多个具有静态生存期的可变引用

为什么可以从函数返回对文字的可变引用?

为什么在这里发生Rust可变借用?

将可变数组引用传递到也需要可变数组引用的函数中时,为什么不声明&mut?

在Rust中返回可变引用

为什么Rust无法在类型构造函数中将可变引用强制转换为不可变引用?

为什么在此处的for循环中必须使用可变引用?

为什么可变借入的顺序在Rust中很重要?

Rust无法分配Option内部可变引用

当Rust中的函数需要可变引用时,为什么不变引用可以匹配?

Rust中的可变按引用传递

为什么我们可以在同一范围内对同一数据有多个可变引用?

为什么存在对 rust 中复制类型的不可变引用?

让多个对象使用不可变引用并同时运行的惯用 Rust 方法

为什么 Rust 不能对不可变变量进行可变借用?

Rust:在递归函数中使用可变引用

为什么通过 Rust 中合法的指针对相同值的多个可变引用

为什么 Rust 不可变引用可以调用 &mut self 方法?

为什么编译器错误会抱怨多个可变引用而不是悬空引用?

多个不可变引用

Rust:为什么当“self: &Self”时“self”不是引用?