Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lifetime issue with a lazy_static mutable variable

Tags:

rust

lifetime

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
like image 283
plailopo Avatar asked Sep 17 '26 11:09

plailopo


1 Answers

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.

like image 60
Chris Emerson Avatar answered Sep 20 '26 06:09

Chris Emerson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!