gpt4 book ai didi

rust - 如果不允许同时使用两个可变引用,那为什么还要允许它们呢?

转载 作者:行者123 更新时间:2023-12-05 08:45:41 26 4
gpt4 key购买 nike

根据文档,

Data races cause undefined behavior and can be difficult to diagnose and fix when you’re trying to track them down at runtime; Rust prevents this problem by refusing to compile code with data races!

除非你是多线程的,否则为什么这是个问题?如果同时访问一个变量及其一个 mut 引用,这个问题不会持续存在吗?

最佳答案

你似乎对某些事情感到困惑。

首先,您的印象似乎是,如果您可变地借用一个值,则可以通过可变引用并直接使用您借用的变量来改变该值。 这不是真的。在借用结束之前,变量实际上是不可用的:

fn main() {
let mut x = 0;
let y = &mut x;

// The following line causes a compile-time error.
// error[E0506]: cannot assign to `x` because it is borrowed
x = 1;

*y = 2;
}

至多可以有一个名称,通过它可以在任何给定时刻修改一个值。由于 xy 可变借用,名称 x 不能用于修改值,直到 y< 借用 已发布。

Why is this a problem at all unless you’re multithreading?

因为改变状态会使引用无效。

考虑你有一个 Vec 的情况。当 Vec 或其任何元素被借用时,您不得修改 Vec 或其任何内容,因为这是不安全的。为什么在单线程代码中会不安全?

如果您有一个项目的引用并且该项目已从 Vec 中删除,会发生什么情况?您引用了无效值或与之前不同的值。

如果向 Vec 添加一个元素,但其内部数组已满,会发生什么情况? Vec 将分配一个新的更大的数组,将所有元素从较小的数组转移到较大的数组中,然后销毁较小的数组。 所有先前存在的元素引用将被此操作无效。

这就是为什么在迭代 Vec 时不能改变它的原因,例如:

for item in some_vec.iter() {
some_vec.push(item.clone());
}

Vec::push() 需要可变地借用 Vec,但迭代需要不变地借用 Vec。你不能同时做这两件事。

Rust 不允许你做这些事情,因为它们根本上是不健全的操作。 Rust 语言的全部目的是在编译时准确捕获这类问题。

请注意,这在 C++ 中也是不安全的,例如——将一个元素添加到 std::vector 可能会使所有现有的无效引用(在重新分配的情况下),当您尝试使用无效引用时,它可能导致未定义的行为。

不同的是,C++ 会接受这种危险的代码。在 C++ 中,检查内存安全是程序员的工作,如果你搞砸了,就会有潜在的灾难性错误,甚至是严重的安全漏洞。

这就是创建 Rust 的原因——承担人类不擅长的这项关键任务,并让编译器为您完成。

关于rust - 如果不允许同时使用两个可变引用,那为什么还要允许它们呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71850155/

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