My code represents a graph in a vector. Each element in the vector (I dubbed it Node
) has a vector of "parents" within the same graph. And it computes its output value with memoization, when needed, by asking its parents to calculate theirs and then aggregating the values.
I consider this a "legal" use case where the Borrow checker gets in the way. If the vector represents a valid, acyclic graph, there is no reason, not to implement it as I do.
struct Node {
parents: Vec<usize>,
output: Option<i8>
}
type Cluster = Vec<Node>;
impl Node {
fn new(ps:&[usize]) -> Self {
Node {
parents: ps.to_vec(),
output: None
}
}
fn calc(&mut self,cluster: &mut Cluster) -> i8 {
match self.output {
Some(out) => out,
None => {
let mut acc: i32 = 0;
for parent_index in &self.parents {
acc += (cluster[*parent_index].calc(cluster)) as i32;
}
let out = (acc / self.parents.len() as i32) as i8;
self.output = Some(out);
out
}
}
}
fn reset(&mut self) {
self.output = None;
}
fn set(&mut self, value: i8) {
self.output = Some(value);
}
}
fn main() {
// input 0 input 1 hidden 0 output 0
let mut c: Cluster = vec![Node::new(&[]), Node::new(&[]), Node::new(&[0,1]), Node::new(&[2])];
c[0].set(42);
c[1].set(11);
let result = c[3].calc(&mut c);
println!("result = {}", result);
}
error[E0499]: cannot borrow
*cluster
as mutable more than once at a time
Of course, the code above is just the minimal reproducable show case of my problem. So, any ideas, how I can teach the Rust bear this new trick?