Farhan Abrol
Farhan Abrol

Reputation: 39

immutable and mutable reference needed for object inside struct

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

Answers (1)

Farhan Abrol
Farhan Abrol

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

Related Questions