Search code examples
ruststatichashmap

Global mutable HashMap in a library


I want to have an extendable dictionary linking together Object with a &'static str inside my library. HashMap seems like the right data structure for this, but how do I make it global, initialised on declaration and mutable?

So something like this:

use std::collections::HashMap;

enum Object { A, B, C }

const OBJECT_STR: &'static [&'static str] = &[ "a", "b", "c" ];

static mut word_map: HashMap<&'static str, Object> = {
    let mut m = HashMap::new();
    m.insert(OBJECT_STR[0], Object::A);
    m.insert(OBJECT_STR[1], Object::B);
    m.insert(OBJECT_STR[2], Object::C);
    m
};

impl Object {
...
}

Solution

  • This would be possible with the lazy_static crate. As seen in their example. Since mutablity accessing a static variable is unsafe, it would need to wrapped into a Mutex. I would recommend not making the HashMap public, but instead provide a set of methods that lock, and provide access to the HashMap. See this answer on making a globally mutable singleton.

    #[macro_use]
    extern crate lazy_static;
    
    use std::collections::HashMap;
    use std::sync::Mutex;
    
    lazy_static! {
        static ref HASHMAP: Mutex<HashMap<u32, &'static str>> = {
            let mut m = HashMap::new();
            m.insert(0, "foo");
            m.insert(1, "bar");
            m.insert(2, "baz");
            Mutex::new(m)
        };    
    }
    
    fn main() {
        let mut map = HASHMAP.lock().unwrap();
        map.insert(3, "sample");
    }