简体   繁体   中英

Lifetime issue with a lazy_static mutable variable

I use lazy_static to keep a HashMap in the memory. With two methods I am adding and getting elements, but I am having some problems with lifetimes.

This is my code:

#[macro_use]
extern crate lazy_static;

use std::sync::Mutex;
use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: Mutex<HashMap<String, Foo>> = Mutex::new({
        let mut m = HashMap::new();
        m.insert("one".to_string(), Foo{param1:"foo1".to_string(),    param2:"foo2".to_string()} );
        m.insert("two".to_string(), Foo{param1:"bar1".to_string(), param2:"bar2".to_string()});
        m
    });
}

pub struct Foo{
    param1: String,
    param2: String,
}

pub fn ins_val(name: String, f: Foo){
    HASHMAP.lock().unwrap().insert(name, f);
}

pub fn get_val(k: &str) -> Option<&Foo>{
    HASHMAP.lock().unwrap().get(k)
}

And this is the error:

HASHMAP.lock().unwrap().get(k) 
^^^^^^^^^^^^^^^^^^^^^^^
reference must be valid for the anonymous lifetime #1 defined on the block

Rust is correctly preventing a bug here.

Your get_val function is trying to return a reference into HASHMAP , but this isn't safe unless you continue holding the lock, as someone else could otherwise come and modify the map under your feet.

You need to either keep the lock until you return the value (by returning the mutex guard along with the value; for example using MutexGuardRef from the owning_ref crate), or copy the value instead of returning a reference:

pub fn get_val(k: &str) -> Option<Foo> {
    HASHMAP.lock().unwrap().get(k).cloned()
}

With this implementation Foo would of course need to implement Clone .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM