#[derive(Debug)]
struct Test{
str1 : Option<String>,
str2 : Option<String>,
}
fn main() {
let mut test = Test{
str1 : Some(String::from("str1")),
str2 : Some(String::from("str2"))
};
let str1 = test.str1.as_mut().unwrap();
let str2 = test.str2.as_mut().unwrap();
*str1 = String::from("nonono1");
*str2 = String::from("nonono2");
println!("{:?}", test);
}
use std::sync::{
Arc, Mutex
};
#[derive(Debug)]
struct Test{
str1 : Option<String>,
str2 : Option<String>,
}
fn main() {
let test = Test{
str1 : Some(String::from("str1")),
str2 : Some(String::from("str2"))
};
let test = Arc::new(Mutex::new(test));
let mut test = test.lock().unwrap();
let str1 = test.str1.as_mut().unwrap();
*str1 = String::from("nonono1");
let str2 = test.str2.as_mut().unwrap();
*str2 = String::from("nonono2");
println!("{:?}", test);
}
use std::sync::{
Arc, Mutex
};
#[derive(Debug)]
struct Test{
str1 : Option<String>,
str2 : Option<String>,
}
fn main() {
let test = Test{
str1 : Some(String::from("str1")),
str2 : Some(String::from("str2"))
};
let test = Arc::new(Mutex::new(test));
let mut test = test.lock().unwrap();
let str1 = test.str1.as_mut().unwrap();
let str2 = test.str2.as_mut().unwrap();
*str1 = String::from("nonono1");
*str2 = String::from("nonono2");
println!("{:?}", test);
}
I want to mutably borrow two parts of a structure wrapped with Arc<Mutex<>> at the same time. Is this possible?
The issue is that when you call lock()
it doesn't actually return &mut Test
, it returns MutexGuard<Test>
. Then when you access a field, it is accessed through the impl DerefMut
on MutexGuard
. Dereferencing through DerefMut
causes the whole MutexGuard
to be mutably borrowed, instead of just the field when you otherwise access it directly.
You can resolve the issue, by upfront dereferencing MutexGuard
into &mut Test
by doing:
let mut test = test.lock().unwrap();
let test: &mut Test = &mut test;
Which when putting it all together, looks like this (playground):
use std::sync::{Arc, Mutex};
#[derive(Debug)]
struct Test{
str1 : Option<String>,
str2 : Option<String>,
}
fn main() {
let test = Test{
str1 : Some(String::from("str1")),
str2 : Some(String::from("str2"))
};
let test = Arc::new(Mutex::new(test));
let mut test = test.lock().unwrap();
let test: &mut Test = &mut test;
let str1 = test.str1.as_mut().unwrap();
let str2 = test.str2.as_mut().unwrap();
*str1 = String::from("nonono1");
*str2 = String::from("nonono2");
println!("{:?}", test);
}