Rfcs: Add HashMap.entry_or_clone() method

Created on 11 Jul 2015  路  8Comments  路  Source: rust-lang/rfcs

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.

T-libs

Most helpful comment

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).

All 8 comments

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).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Diggsey picture Diggsey  路  3Comments

onelson picture onelson  路  3Comments

mahkoh picture mahkoh  路  3Comments

torkleyy picture torkleyy  路  3Comments

camden-smallwood-zz picture camden-smallwood-zz  路  3Comments