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

标签 rust

来自 Rust 文档:

mutable references have one big restriction: you can have only one mutable reference to a particular piece of data in a particular scope.

文档中的示例确实支持此声明:

let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s;
println!("{}, {}", r1, r2);

但这对我来说有点误导。当最后一行中的 print 语句被删除时,程序可以编译并正常运行(尽管有一些警告)。后来在文档中,他们说这就是 Rust 处理数据竞争的方式。我还没有达到他们解释线程和并行编程的程度,但我想仍然值得问一下在以下情况下我们如何防止数据竞争:

fn main() {
    let mut name: String = String::from("Devashish");

    // assume that fun1 was called from a new thread
    fun1(&mut name);

    // fun1 and fun2 are being executed in parallel at this point
    fun2(&mut name);
}

fn fun1(re: &mut String) {
    println!("From fun1: {}", re);
}

fn fun2(re: &mut String) {
    println!("From fun2: {}", re);
}

在上述情况下,我们如何防止数据竞争?

最佳答案

在这种情况下,引用是匿名的。调用 fun1&mut name 引用的生命周期 is the enclosing statement ,即 fun1(&mut name);

因此第一个可变引用的生命周期在第二个可变引用开始之前结束

如果您明确声明了引用,则顺序将确定是否存在冲突(感谢 NLL )。

这无效:

let r1 = &mut name;
let r2 = &mut name;
fun1(r1);
fun2(r2);

这是有效的(使用足够新的 rustc 版本):

let r1 = &mut name;
fun1(r1);
let r2 = &mut name;
fun2(r2);

因为借用检查器可以确定在声明 r2 时不再使用 r1。

如果您尝试在 fun1 后面放置一个新线程,您可能会发现:不,您不能将可变借用从 fun1 内部传递给另一个线程。一旦 fun1 结束,可变借用就会被释放,这在语法上是有保证的。

关于rust - 为什么我们可以在同一范围内对同一数据有多个可变引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57055461/

相关文章:

rust - 在同一个选项上匹配多次会产生太多对 self 的可变引用

rust - 使用into_serde反序列化字符串使应用程序 panic

rust - 从 block 表达式退出? (类似于 "return"函数)

unit-testing - 是否可以从测试中访问私有(private)结构字段?

rust - 我可以以某种方式修改 '&' 数组吗?

rust - 如何解决这个 Rust 生命周期问题?

rust - 派生特征会导致意外的编译器错误,但手动实现有效

rust - 我如何处理 Rust 中的包装器类型不变性?

rust - 如何使 Rust 函数 `zip_map` 采用二元函数而不是以二元组作为参数的一元函数?

rust - 编写通用交换函数