I am learning Rust by exercise. In this file the goal is to update cells as in a spreadsheet: when a value changes, all cells that are derived from it have to be recalculated. Here, those are called that cell's parents.
Updating a cell value proves no problem, but updating the parents gets me fighting the borrow checker. When I have retrieved the cell from a HashMap
and updated the value, I no longer need a mutable reference - so I tried wrapping it in an immutable reference instead. That way I only have to find it once.
But it seems Rust figures since I originally got my immutable reference from a borrowed &mut self
, it must still be tied to it. This obviously prevents me from reusing self
a second time.
use std::collections::HashMap;
use std::vec::Vec;
struct Cell {
value: i32,
parents: Vec<u32>,
}
pub struct Sheet {
table: HashMap<u32, Cell>,
}
impl Sheet {
pub fn set_value(&mut self, identifier: u32, new_value: i32) {
let mut updated_cell: Option<&Cell> = None;
if let Some(cell) = self.table.get_mut(&identifier) {
let Cell { value, .. } = cell;
*value = new_value;
updated_cell = Some(cell);
}
if let Some(cell) = updated_cell {
recalculate(self, &cell.parents);
}
}
}
fn recalculate(_sheet: &mut Sheet, _cells: &[u32]) {}
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src/lib.rs:20:16
|
16 | if let Some(cell) = self.table.get_mut(&identifier) {
| ---------- first mutable borrow occurs here
...
22 | recalculate(self, &cell.parents);
| ^^^^ ------------- first borrow later used here
| |
| second mutable borrow occurs here
I want to know if there is a solution which avoids searching a second time or taking an unnecessary vector copy. I have tried to adjust the code many times, but not all of the syntax is yet clear to me yet.