3

I'm writing a function that works with a HashMap and at various points in the function I want to check if any of the values in the map meet a condition and if any does return the key for just one of the entries that meets the condition.

So far, I tried to first iterate over references to check my condition, and then use remove_entry to get an owned copy of the key rather than a borrow:

use std::{collections::HashMap, hash::Hash}; fn remove_first_odd<K: Hash + Eq>(map: &mut HashMap<K, u64>) -> Option<K> { let maybe_entry = map.iter().find(|(_, &value)| value & 1 == 1); match maybe_entry { Some((key_ref, _value_ref)) => { let (key_owned, _value_owned) = map.remove_entry(key_ref).unwrap(); Some(key_owned) } None => None, } } 

but this fails borrow checking, because I can't mutate the map while I am still holding a reference to one of the keys in it:

error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable --> src/lib.rs:8:45 | 4 | let maybe_entry = map.iter().find(|(_, &value)| value & 1 == 1); | --- immutable borrow occurs here ... 8 | let (key_owned, _value_owned) = map.remove_entry(key_ref).unwrap(); | ^^^^------------^^^^^^^^^ | | | | | immutable borrow later used by call | mutable borrow occurs here 

I believe that this is possible, because as long as remove_entry only dereferences my key before mutation and not after, this should be sound.

So is there a safe API to do this? If not, can one be created?

Note that:

  • I can't clone my keys because they are generic without a clone bound
  • I can't consume the HashMap with something like .into_iter()
  • I only need to remove a single entry, not all of the entries that match
5

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.