Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I return something from HashMap.get’s None case?

Tags:

rust

I'm wondering with the best practice to handle the None result in getting values from a HashMap. Given I have a simple function:

pub fn get_value(&self, value: String) -> &String {

One could get the value from the HashMap with unwrap:

my_map.get(&"hello".to_string()).unwrap()

But I don’t want it to panic if it gets None. What else can I do?

match self.os_config.get(&value) {
    Some(val) => return &val,
    None =>  //?? cannot return a String::new().. as it is temporal?
}
like image 407
Richard Donovan Avatar asked Jul 16 '15 21:07

Richard Donovan


2 Answers

For starters, &String is a type that should never exist in a signature; you should take the more general &str. String is specifically an owned string, while &str is a string slice. Because String implements Deref<Target = str>, &String coerces to &str.

When dealing with hash map keys, you should also take &str rather than &String, and you should avoid taking String if all you need is &str; you don’t need to consume the string. You can index a HashMap<String, _> with &str just fine.

The type of a string literal is &'static str; &'static str will quite happily coerce to &'a str for any 'a, so you can quite happily use an empty string literal on the None branch. Here’s the result:

pub fn get_value(&self, value: &str) -> &str {
    match self.os_config.get(value) {
        Some(val) => val,
        None => "",
    }
}

This can also be written using the handy unwrap_or method:

pub fn get_value(&self, value: &str) -> &str {
    self.os_config.get(value).unwrap_or("")
}

For this reason, returning an Option<&str> is perhaps not so tedious; other places can add .unwrap_or("") if they want to. Of course, it all depends on the desired semantics.

like image 146
Chris Morgan Avatar answered Nov 09 '22 11:11

Chris Morgan


If you need to return an arbitrary type or result, such that you can't use a 'static reference, you can return a Cow type from the function.

A simple demo is at Holy std::borrow::Cow!, but you basically just have to wrap it in a Cow::Borrowed normally and a Cow::Owned for the error case.

like image 36
Veedrac Avatar answered Nov 09 '22 11:11

Veedrac