Twan van Laarhoven
Twan van Laarhoven

Reputation: 2602

How to look up values in a HashMap<Option<String>, V> without copying?

I have a HashMap with Option<String> keys; is it possible to do lookups with a key of type Option<&str>? I know I can use a &str to lookup in a HashMap<String, V> because str implements Borrow<String>.

Do I have to convert to an owned string just to do a lookup?

Upvotes: 4

Views: 1068

Answers (1)

apetranzilla
apetranzilla

Reputation: 5919

It's slightly less efficient, but you could use Cow here. It avoids the problem with the Borrow trait by instead having a single type that can represent either a reference or an owned value, like so:

use std::borrow::Cow;
use std::collections::HashMap;

fn main() {
    let mut map = HashMap::<Option<Cow<'static, str>>, i32>::new();
    map.insert(None, 5);
    map.insert(Some(Cow::Borrowed("hello")), 10);
    map.insert(Some(Cow::Borrowed("world")), 15);
    
    // works with None and constant string slices...
    assert_eq!(map.get(&None), Some(&5));
    assert_eq!(map.get(&Some(Cow::Borrowed("hello"))), Some(&10));
    
    // ...and also works with heap-allocated strings, without copies
    let stack = String::from("world");
    assert_eq!(map.get(&Some(Cow::Borrowed(&stack))), Some(&15));
}

Upvotes: 1

Related Questions