gpt4 book ai didi

multithreading - 为什么 Rust 会阻止多重可变引用?

转载 作者:行者123 更新时间:2023-11-29 08:02:43 25 4
gpt4 key购买 nike

就像主题中一样,为什么 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

关于multithreading - 为什么 Rust 会阻止多重可变引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58364807/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com