像本主题一样,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] 删除。
我来说两句