I can't seem to get this code to allow me to use refcell for interior mutability.
I'm using refcells, and I use the borrow_mut()
function like so:
struct AllMonkeys<'a>(HashMap<&'a str, RefCell<Monkey<'a>>>);
impl<'a> AllMonkeys<'a> {
fn calculate(&self, name: &str) -> i64 {
match self.0[name].borrow_mut() {
Monkey::Val(num) => num,
mut monkey @ Monkey::Job {
left,
right,
operand,
} => {
let left_val = self.calculate(left);
let right_val = self.calculate(right);
let val = match operand {
Operand::Plus => left_val + right_val,
Operand::Minus => left_val - right_val,
Operand::Mult => left_val * right_val,
Operand::Div => left_val / right_val,
};
*monkey = Monkey::Val(val);
val
}
}
}
}
this complains of a type missmatch:
error[E0308]: mismatched types
--> src/day21.rs:12:13
|
11 | match self.0[name].borrow_mut() {
| ------------------------- this expression has type `RefMut<'_, day21::Monkey<'a>>`
12 | Monkey::Val(num) => num,
| ^^^^^^^^^^^^^^^^ expected `RefMut<'_, Monkey<'_>>`, found `Monkey<'_>`
|
= note: expected struct `RefMut<'_, day21::Monkey<'a>, >`
found enum `day21::Monkey<'_>`
fair enough. so, I'll try dereferencing the refmut to make the type checker happy:
fn calculate(&self, name: &str) -> i64 {
match *self.0[name].borrow_mut() {
Monkey::Val(num) => num,
mut monkey @ Monkey::Job {
left,
right,
operand,
} => {
let left_val = self.calculate(left);
let right_val = self.calculate(right);
let val = match operand {
Operand::Plus => left_val + right_val,
Operand::Minus => left_val - right_val,
Operand::Mult => left_val * right_val,
Operand::Div => left_val / right_val,
};
monkey = Monkey::Val(val);
val
}
}
}
but now the type checker complains that I'm moving out of a reference:
error[E0507]: cannot move out of dereference of `RefMut<'_, day21::Monkey<'_>>`
--> src/day21.rs:11:15
|
11 | match *self.0[name].borrow_mut() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
12 | Monkey::Val(num) => num,
13 | monkey @ Monkey::Job {
| ------ data moved here
...
16 | operand,
| ------- ...and here
|
= note: move occurs because these variables have types that don't implement the `Copy` trait
help: consider removing the dereference here
I'm stumped, what do I do?
full code(I'm using include_str!()
so this won't compile unless you add a file at the expected location): Playground