I get an error about mutable borrow fail in Mutex.
Here is the code.
It's Ok now. But it will fail to compile if uncommenting the 2 lines, which wraps the state into a Mutex and unwraps it out.
Why does the Mutex make the difference?
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");
}
The error if uncommenting the 2 lines:
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
===EDIT===
It's Ok if changing some code order:
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");
It seems that v1 holds a reference of state. If v1 ends, it drops the reference, and then state can be borrowed again.
Why v1 holds the reference of state?
====EDIT====
@Alexey Larionov gave the answer. And I find a similar question. And I should get the state out of the MutexGuard manually by deref_mut(). So adding this line makes things ok:
let state = state.deref_mut();