1

I'm working on a problem similar to the one in How to lookup from and insert into a HashMap efficiently?. I have a map with String keys and I want to write a function that returns the value for a key if it exists, or calculates and inserts it if it doesn't.

From the answer to that question, I understand that the proper way to do this is to use an Entry. So I wrote this:

fn get_or_calculate(&self, key: &str) -> u64 {
    match self.map.entry(key) {
        Entry::Occupied(o) => o.get(),
        Entry::Vacant(v) => v.insert(2 + 2),
    }
}

Now my problem is that I can no longer use &str to lookup values. While map.get() happily accepts a &str, map.entry() needs a String that it can take ownership of:

error[E0308]: mismatched types
  --> src/lib.rs:15:30
   |
15 |         match self.map.entry(key) {
   |                              ^^^
   |                              |
   |                              expected struct `std::string::String`, found &str
   |                              help: try using a conversion method: `key.to_string()`
   |
   = note: expected type `std::string::String`
              found type `&str`

I could just use to_string(), but I understand that may be costly. It feels a bit unnecessary - since the Entry doesn't outlive my function it would not need to take ownership of the string.

Is there any way to use Entry with &str even though the key is String? Can I somehow rewrite the code without using an Entry?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Anders
  • 8,307
  • 9
  • 56
  • 88

0 Answers0