I keep stumbling on a pattern in my Rust programs that always puts me at odds with the borrow-checker. Consider the following toy example:
use std::sync::{Arc,RwLock};
pub struct Test {
thing: i32,
}
pub struct Test2 {
pub test: Arc<RwLock<Test>>,
pub those: i32,
}
impl Test {
pub fn foo(&self) -> Option<i32> {
Some(3)
}
}
impl Test2 {
pub fn bar(&mut self) {
let mut test_writer = self.test.write().unwrap();
match test_writer.foo() {
Some(thing) => {
self.add(thing);
},
None => {}
}
}
pub fn add(&mut self, addme: i32) {
self.those += addme;
}
}
This doesn't compile because the add
function in the Some
arm tries to borrow self mutably, which was already borrowed immutably just above the match statement in order to open the read-write lock.
I've encountered this pattern a few times in Rust, mainly when using RwLock
. I've also found a workaround, namely by introducing a boolean before the match
statement and then changing the value of the boolean in the Some
arm and then finally introducing a test on this boolean after the match statement to do whatever it is I wanted to do in the Some
arm.
It just seems to me that that's not the way to go about it, I assume there's a more idiomatic way to do this in Rust - or solve the problem in an entirely different way - but I can't find it. If I'm not mistaken the problem has to do with lexical borrowing so self
cannot be mutably borrowed within the arms of the match statement.
Is there an idiomatic Rust way to solve this sort of problem?