【发布时间】:2021-08-31 09:29:05
【问题描述】:
我收到关于 Mutex 中可变借用失败的错误。
这里是代码。
现在好了。但是如果取消注释这 2 行,它将无法编译,这会将 state 包装到 Mutex 中并将其解包出来。
为什么 Mutex 会有所作为?
use std::collections::HashMap;
use std::sync::Mutex;
struct State {
h1: HashMap<String, String>,
h2: HashMap<String, String>,
}
fn main() {
let mut state = State {
h1: HashMap::new(),
h2: HashMap::new(),
};
// It fails to compile if uncommenting these 2 lines!
//let state = Mutex::new(state);
//let mut state = state.lock().unwrap();
let v1 = state.h1.get_mut("abc").unwrap();
let v2 = state.h2.get_mut("abc").unwrap();
v1.push_str("123");
v2.push_str("123");
}
取消注释这两行的错误:
error[E0499]: cannot borrow `state` as mutable more than once at a time
--> tmp.rs:20:14
|
19 | let v1 = state.h1.get_mut("abc").unwrap();
| ----- first mutable borrow occurs here
20 | let v2 = state.h2.get_mut("abc").unwrap();
| ^^^^^ second mutable borrow occurs here
21 | v1.push_str("123");
| -- first borrow later used here
===编辑===
如果更改一些代码顺序就可以了:
let state = Mutex::new(state);
let mut state = state.lock().unwrap();
let v1 = state.h1.get_mut("abc").unwrap();
v1.push_str("123");
let v2 = state.h2.get_mut("abc").unwrap();
v2.push_str("123");
似乎v1 拥有state 的引用。如果v1 结束,它会丢弃引用,然后state 可以再次借用。
为什么v1 持有state 的引用?
====编辑====
@Alexey Larionov 给出了答案。我找到了一个类似的question。我应该通过deref_mut() 手动将state 从 MutexGuard 中取出。所以添加这一行就可以了:
let state = state.deref_mut();
【问题讨论】:
-
如果你足够勇敢(或鲁莽!)你可以实现借用拆分:stackoverflow.com/a/68581212/2588800。否则,您可以执行@Netwave 建议的操作或使用“内部可变性”
标签: rust borrow-checker