Creating lazily evaluated statics

We have seen in previous chapters how, in nightly Rust, it is possible to call some trivial constant functions that are evaluated at compile time. Nevertheless, this might not be enough for our needs, and we might not even want to use nightly Rust.

In this case, we can use a great crate, and the macro with the same name—lazy_static. This macro allows us to create static variables that will run the code to be generated on their first use. Let's check it, for example, for a HashMap. Creating a HashMap or adding values to it cannot be done during compile time. As we saw in previous chapters, this can be improved by using the phf crate. But what if we want to add values to the HashMap based on some environment variable? This is where lazy_static!{} comes in:

#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
static ref MY_MAP: HashMap<&'static str, &'static str> = {
use std::env;

let mut map = HashMap::new();
if let Ok(val) = env::var("GEN_MAP") {
if val == "true" {
map.insert("firstKey", "firstValue");
map.insert("secondKey", "secondValue");
}
}

map
};
}


fn main() {
for (key, value) in MY_MAP.iter() {
println!("{}: {}", key, value);
}
}

As you can see, we create a HashMap at runtime the first time we use it, so it will not be defined until we call MyMap.iter(), and if we were to use it again, it wouldn't need to be recreated. Not only that, it depends on the GEN_MAP environment variable. So, if we run the program with cargo run, it won't show anything; but if we run it with GEN_MAP=true cargo run, it will show the two key-values.

Under the hood, this will create a new type that implements Deref to HashMap. This will call to the initialize() function the first time it tries to get to the underlying type, generating the actual HashMap. This is very efficient if you only want one initialization of something you will be using more than once.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.61.218