There are a handful of methods on HashMap
to achieve these sorts of complex cases. Most notably, for your case, HashMap::entry
and Entry::or_insert_with
:
pub fn get_type<'a>(&'a mut self, k: i32) -> &'a i32 {
self.types.entry(k).or_insert_with(|| {
let value = self.next;
self.next += 1;
value
})
}
In your case, however, there’s the borrow of self
inside, so that won’t do.
We thus shift the borrow of self.next
outside of the closure so the compiler can reason about it as disjoint from self.types
. Problem solved with only one lookup, as it should be.
pub fn get_type<'a>(&'a mut self, k: i32) -> &'a i32 {
let next = &mut self.next;
self.types.entry(k).or_insert_with(|| {
let value = *next;
*next += 1;
value
})
}