How to use the get() HashMap method for structs


#1

Hi all,

The get() method returns an Option<T> on a HashMap. When the stored object is a struct, one can’t use such constructs as:

map.get(&somekey).x

if x is a field of a struct.

Example:

struct Number {
    french: String,
    spanish: String
}


fn main() {
    use std::collections::HashMap;
    
    let mut map: HashMap<i8,Number> = HashMap::new();
    
    let one = Number { french: "un".to_string(), spanish: "uno".to_string() };
    let two = Number { french: "deux".to_string(), spanish: "dos".to_string() };
    
    map.insert(1, one);
    map.insert(2, two);
    
    let n1 = map.get(&1).french;
}

doesn’t compile. I know that the key 1 exists, so why returning an > Option ? Always needs a match ?

Thanks for your help.


#2

It’s because the definition of get(), where the HashMap is defined, doesn’t know that that key exists. get() can’t guarantee that every key you try to use with it will have a member in the hash table, so it must use the Option type so it can return something sensible when the key doesn’t have a matching entry. You can avoid using a match here by using unwrap() instead; unwrap() returns the object inside an Option and panics when it doesn’t exist:

let n1 = map.get(&1).unwrap().french;

Keep in mind that unwrap() is basically telling the compiler that you always expect the thing that you’re unwrapping exists; if it doesn’t your program will panic!


#3

It shows my few knowledge of the language so far :wink:

Thanks a lot for the hint.


#4

Look at the rest of Option’s API - there are additional methods that allow you to “unwrap” safely and functionally/ergonomically. Since the language doesn’t have the notion of null, absence of values is always signaled via Option (which is really nice IMO).