I have some objects that are constructed, stored in a single data structure, and updated during a run of my binary. Sometimes they get lonely and need friends, so they need to be able to search through the storage, locate a friend, remember the friend's identity, and tell the friend who they are.
struct Obj {
id: i32,
friend: Option<i32>,
}
impl Obj {
fn find_friend(&mut self, storage: &mut HashMap<i32, Obj>) {
// let's pretend we found this friend in storage
let friend_id = 1;
let new_friend = storage.get_mut(&friend_id).unwrap();
self.friend = Some(new_friend.id);
new_friend.friend = Some(self.id);
}
}
fn main() {
let mut storage: HashMap<i32, Obj> = HashMap::new();
let obj = Obj {
id: 0,
friend: None,
};
let id = obj.id;
storage.insert(id, obj);
// time passes
let obj_again = storage.get_mut(&id).unwrap();
obj_again.find_friend(&mut storage);
}
Unfortunately I get in fights with the borrow checker:
error[E0499]: cannot borrow `storage` as mutable more than once at a time
--> src\main.rs:190:22
|
189 | let obj_again = storage.get_mut(&id).unwrap();
| ------- first mutable borrow occurs here
190 | obj_again.find_friend(&mut storage);
| ^^^^^^^ second mutable borrow occurs here
191 | }
| - first borrow ends here
error: aborting due to previous error
How can I structure this code such that I can fetch a reference to an object out of storage and then allow it to mutate itself, its compatriots, and the data structure that contains them?
Edit: I'm not sure that this is a duplicate of the question "How do I get two mutable references into a container?" This is "How can an object inside a container mutate itself if it also needs to be able to mutate its container?". Sorry if that wasn't clear.