I'm trying to efficiently look up or insert an item into a HashMap
that owns both its keys and its values.
According to How to lookup from and insert into a HashMap efficiently?, the Entry
API is the way to do this.
However, when inserting a new item, I also need access to the key.
Since HashMap::entry
consumes the key, I cannot do the following, which fails with error[E0382]: borrow of moved value: 'index'
:
let mut map: HashMap<String, Schema> = ...;
let index: String = ...;
let schema = map
.entry(index)
.or_insert_with(|| Schema::new(&index));
The simplest way to get this working seems to be as follows:
let schema = match map.entry(index) {
Entry::Occupied(e) => e.into_mut(),
Entry::Vacant(e) => {
// VacantEntry::insert consumes `self`,
// so we need to clone:
let index = e.key().to_owned();
e.insert(Schema::new(&index))
}
};
If only or_insert_with
would pass the Entry
to the closure that it calls, it would have been possible to write the above code like this:
let schema = map
.entry(index)
.or_insert_with_entry(|e| {
let index = e.key().to_owned();
Schema::new(&index)
});
Did I overlook something? What would be the best way to write this code?