Boris Bera
Boris Bera

Reputation: 898

Get value out of optional HashMap only when present

I have a bit of code that loads a HashMap and then retrieves a value with the map.get(...) method. In my case, it's possible that I may not be able to return a HashMap, so in reality I'm dealing with an Option<HashMap>.

I've managed to isolate my problem in the following snippet:

use std::collections::HashMap;

type MyMap = HashMap<String, String>;

fn get_map() -> Option<MyMap> {
    // In the real case, we may or may not be able to return a map
    Some(MyMap::new())
}

fn main() {
    let res = get_map().and_then(|h| h.get("foo"));
    println!("{:?}", res)
}

I get the following compilation error:

error[E0597]: `h` does not live long enough
  --> src/main.rs:11:38
   |
11 |     let res = get_map().and_then(|h| h.get("foo"));
   |                                      ^          - `h` dropped here while still borrowed
   |                                      |
   |                                      borrowed value does not live long enough
12 |     println!("{:?}", res)
13 | }
   | - borrowed value needs to live until here

(Playground)

I think that I get what's going on here:

There are really two questions here:

  1. Am I understanding this correctly?
  2. How do I fix this?

Upvotes: 1

Views: 712

Answers (1)

Boiethios
Boiethios

Reputation: 42759

Call Option::as_ref. It converts an Option<T> to Option<&T>:

use std::collections::HashMap;

type MyMap = HashMap<String, String>;

fn get_map() -> Option<MyMap> {
    // In the real case, we may or may not be able to return a map
    Some(MyMap::new())
}

fn main() {
    let map = get_map();
    let res = map.as_ref().and_then(|h| h.get("foo"));
    println!("{:?}", res)
}

What happened is that and_then consumes the Option; so you were trying to hold a reference to the consumed data.

The same rule applies for the returned value of get_map(): if it is not stored in its own variable, it remains a temporary value, to which you cannot hold a reference.

Upvotes: 2

Related Questions