You can solve your specific problem by doing a double object search. First, always borrow from a hash map to collect the information needed to update the item. Then, finally, update the theme using the collected information using hash map borrowing:
fn move_toward_target(beetles: &mut Beetles, beetle_id: i32) { if let Some(subject_target_id) = beetles.get(&beetle_id).map(|b| b.target_id) { let mut target_xy = None; // example if let Some(target) = beetles.get(&subject_target_id) { // collect information about target relevant for updating subject target_xy = Some((target.x, target.y)) // example } let subject = beetles.get_mut(&beetle_id).unwrap(); // update subject using collected information about target if let Some((target_x, target_y)) = target_xy{ // example subject.x = target_x; subject.y = target_y; } } }
However, most likely, you will encounter similar and more complex problems with your bugs in the future, because bugs are your central game objects, which you probably want to refer to variably and invariably at the same time at several places in your code. Therefore, it makes sense to wrap your bugs in std::cell::RefCell s, which check borrowing rules dynamically at runtime. This gives you more flexibility when linking to bugs in your hash map:
fn main() { let mut beetles: Beetles = HashMap::new(); beetles.insert(0, RefCell::new(Beetle::new())); beetles.insert(1, RefCell::new(Beetle::new())); set_target(&mut beetles, 0, 1); move_toward_target(&mut beetles, 0); } fn set_target(beetles: &mut Beetles, subject_id: i32, target_id: i32) { if let Some(mut subject) = beetles.get_mut(&subject_id).map(|b| b.borrow_mut()) { subject.target_id = target_id; } } fn move_toward_target(beetles: &mut Beetles, beetle_id: i32) { if let Some(mut subject) = beetles.get(&beetle_id).map(|b| b.borrow_mut()) { if let Some(target) = beetles.get(&subject.target_id).map(|b| b.borrow()) {
Updated Beetles Type:
type Beetles = HashMap<i32, RefCell<Beetle>>;
source share