Reputation: 39
So the setup is a function on a struct that mutates some interior values (hence passed in &mut self). I'm running into a situation where I believe because I'm using a loop - rust tries to take an immutable reference to field of self, which is already taken mutably upfront
node_content: HashMap<Id, Node<T>>;
pub fn set_val(&mut self,..) {
for id in self.node_content.iter() {
self.some_function();
}
...
for id in list {
node = self.node_content.get_mut(id).unwrap();
params=Vec::new()
for v in node.upstream_nodes() {
new_node = self.node_content.get(v).unwrap();
params.push(new_node)
}
node.x = 10// some updates to node
}
}
I get
cannot borrow node_content as immutable because it is also borrowed as mutable immutable borrow occurs here
I tried storing a direct mut reference to node_content outside of self, but then I can't do the calls to the some_function since I've used the self reference.
I think RefCells should help here ? But I'm not sure since when I try to use them, I run into the same problem of immutable and mutable references at runtime
let node_content = RefCell::new(&mut self.node_content);
for id in list {
let mut nc = node_content.borrow_mut();
node = nc.get_mut(id).unwrap();
params=Vec::new()
for v in node.upstream_nodes() {
let nc = node_content.borrow(); //~~~thread 'x' panicked at 'already mutably borrowed: BorrowError'
new_node = nc.get(v).unwrap();
params.push(new_node)
}
node.x = 10// some updates to node
}
Upvotes: 0
Views: 669
Reputation: 39
From @harmic's suggestion, I can solve this by scoping things right
node_content: HashMap<Id, Node<T>>;
pub fn set_val(&mut self,..) {
for id in self.node_content.iter() {
self.some_function();
}
...
for id in list {
{
node = self.node_content.get(id).unwrap();
params=Vec::new()
for v in node.upstream_nodes() {
new_node = self.node_content.get(v).unwrap();
params.push(new_node)
}
}
node = self.node_content.get_mut(id).unwrap();
node.x = 10// some updates to node
}
}
Is this the most idiomatic option?
Upvotes: 1