Sometimes I have a key type which implements Clone, but for efficiency reasons I don't want to clone it unless it's absolutely necessary.
In this case it would be nice to have a method
my_hash_map.entry_or_clone(&k)
which behaves identically to
my_hash_map.entry(k.clone())
but only bothers to clone k if the key doesn't already exist in my_hash_map.
See also https://internals.rust-lang.org/t/head-desking-on-entry-api-4-0/2156
This is possibly a viable solution in that it's back-compat to add a new method that requires a Clone bound.
Just hit this as well. The entry_or_clone idea sounds good. One thing to consider would probably be that it might end up clattering the API if a method with a clone bound is found soon after adding this.
Asides from that, the name entry_or_clone makes clear whats happening, and should not be too confusing(until the API is possibly expanded later on).
I just posted another alternative to this in #1533.
Just passing by to give a +1, I also just ran into this and am annoyed.
Eh... is that a Github bug? It says I unassigned Gankro, but I did no such thing nor do I have permissions to do so.
Given that it has been 5 years and apparently nobody has found a more elegant solution perhaps it is time to accept that entry_or_clone() is the best option?
I'm really surprised this hasn't been given more attention given that it is a pretty basic flaw and Rust is very focused on performance.
On nightly rust (or stable hashbrown) you can use the raw_entry API which provides this and more.
It needs another design pass though before it can be stabilized. It provides useful functionality, but the very clean initial design became a little mangled when it ran into reality.
You can do what you want as
some_map
.raw_entry_mut()
.from_key(&key)
.or_insert_with(|| (key.clone(), 42));
Note that unlike entry_or_clone this also works for cases like looking up a &str but inserting String (e.g. ToOwned not Clone, or anything else). That said, a buggy impl can corrupt your map IIUC, although not in a memory unsafe way (and no more than a buggy Hash/Eq impl combo, I think).
HashMap::raw_entry tracking issue is rust-lang/rust#56167 (for those following along).
Most helpful comment
On nightly rust (or stable hashbrown) you can use the
raw_entryAPI which provides this and more.It needs another design pass though before it can be stabilized. It provides useful functionality, but the very clean initial design became a little mangled when it ran into reality.
You can do what you want as
Note that unlike
entry_or_clonethis also works for cases like looking up a&strbut insertingString(e.g.ToOwnednotClone, or anything else). That said, a buggy impl can corrupt your map IIUC, although not in a memory unsafe way (and no more than a buggy Hash/Eq impl combo, I think).