Why Rust prevents from multiple mutable references?

不打扰是莪最后的温柔 提交于 2019-12-06 07:31:18

The fact that Rust prevent two mutable references at the same time to prevent data races is a common misconception. This is only one of the reasons. Preventing two mutable references makes it possible to keep invariants on types easily and let the compiler enforce that the invariant are not violated.

Take this peace of C++ code for an example:

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

This is unsafe because you cannot mutate a vector while you are iterating it. Mutating the vector might reallocate its internal buffer, which invalidates all references. In C++, this is a UB. In Python, Java or C# (and probably most other languages), you would get a runtime exception.

Rust however, prevents this kind of issues at compile time:

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

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

gives an error:

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!