为什么我不能从互斥锁防护器可变地借用单独的字段?

问题描述 投票:0回答:1

试图通过MutexGuard获得对各个字段的可变引用:

struct MyObject {
    pub a: i32,
    pub b: i32,
}

fn func_1(mtx: &Mutex<MyObject>) {
    let mut obj = mtx.lock().unwrap();
    let a = &mut obj.a;
    let b = &mut obj.b;

    *a += 1;
    *b *= 2;
}

导致错误:

error[E0499]: cannot borrow `obj` as mutable more than once at a time
  --> src/main.rs:11:18
   |
10 |     let a = &mut obj.a;
   |                  --- first mutable borrow occurs here
11 |     let b = &mut obj.b;
   |                  ^^^ second mutable borrow occurs here
12 |     
13 |     *a += 1;
   |     ------- first borrow later used here

这让我有些困惑。当obj是简单的可变引用(&mut MyObject)时,此方法有效。我以为Deref特性是导致问题的原因,但如果obj&mut Box<MyObject>,它也可以工作。

Rust Playground上查看。

我想念什么?

rust
1个回答
0
投票

Mutex :: lock除了返回其他方法来处理其包含的值之外,还返回RAII锁保护。要获得其包含的值作为&mut(并随后“拆分借用”),您需要:

  • 将防护(由lock返回)保存在一个单独的值中,因为只要访问该值,锁就必须存在。
  • &mut从后卫提取值作为MutexGuard::deref_mut

这里是更新的func_1

use std::ops::DerefMut;

fn func_1(mtx: &Mutex<MyObject>) {
    let mut guard = mtx.lock().unwrap();
    let obj = guard.deref_mut();
    let a = &mut obj.a;
    let b = &mut obj.b;

    *a += 1;
    *b *= 2;
}
© www.soinside.com 2019 - 2024. All rights reserved.