# \`Entry::or\_insert\_with\_key\`

**URL:** <https://internals.rust-lang.org/t/entry-or-insert-with-key/10876>\
**Category:** libs\
**Created:** [August 27, 2019, 6:06pm UTC](https://internals.rust-lang.org/t/entry-or-insert-with-key/10876 "2019-08-27T18:06:57Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Coder-256](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/coder-256/32/6074_2.png) [@Coder-256](https://internals.rust-lang.org/u/Coder-256)\
**Post date:** [August 27, 2019, 6:06pm UTC](https://internals.rust-lang.org/t/entry-or-insert-with-key/10876/1 "2019-08-27T18:06:57Z")

</div>

I am trying to create a struct that memoizes a given function. However, I ended up needing to write code like this:

```
match self.cache.borrow_mut().entry(key) {
    Entry::Occupied(e) => e.into_mut(),
    Entry::Vacant(e) => {
        let value = (self.transform)(e.key());
        e.insert(value)
    }
}

```

Ideally I would be able to use `std::collections::hash_map::Entry::or_insert_with` like this:

```
let entry = self.cache.borrow_mut().entry(key);
entry.or_insert_with(|| (self.transform)(entry.key()));

```

However this doesn't compile because by the time we're in the closure, we've moved `key` into `entry()`, then moved `entry` into `or_insert_with()` so it's not available for the closure to use.

I propose adding a new method to fix this: `or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> &'a mut V`. It works exactly the same as the `or_insert_with` but gives the closure a reference to the key, similarly to the first block of code above. In fact adding this would compact it to:

```
self.cache.borrow_mut().entry(key).or_insert_with_key(&self.transform);

```

Here's a preliminary working implementation:

```
fn or_insert_with_key<'a, F: FnOnce(&K) -> V, K, V>(
    entry: Entry<'a, K, V>,
    default: F,
) -> &'a mut V {
    match entry {
        Entry::Occupied(e) => e.into_mut(),
        Entry::Vacant(e) => {
            let value = default(e.key());
            e.insert(value)
        }
    }
}

// ...

or_insert_with_key(
    self.cache.borrow_mut().entry(key),
    &self.transform,
)
```

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [November 25, 2019, 6:21pm UTC](https://internals.rust-lang.org/t/entry-or-insert-with-key/10876/2 "2019-11-25T18:21:53Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
