试图通过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上查看。
我想念什么?
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;
}