Member-only story
A Brief Discussion on Lazy Loading in Rust
Let’s learn about lazy loading in Rust today.
once_cell
The once_cell
library provides two new cell-like types, un sync :: OnceCell
and sync :: OnceCell
. OnceCell
may store any non- Copy
type, can be assigned at most once, and provides direct access to the stored content.
The core API is roughly as follows:
impl<T> OnceCell<T> {
const fn new() -> OnceCell<T> { ... }
fn set(&self, value: T) -> Result<(), T> { ... }
fn get(&self) -> Option<&T> { ... }
}
Note that like RefCell
and Mutex
, the set
method only requires a shared reference. Due to the single assignment limitation, get
can return & T
instead of Ref < T >
or MutexGuard < T >
.
Additionally, once_cell
have a Lazy < T >
type based on OnceCell
that provides the same API as the lazy_static!
macro, but without using any macros:
use std::{sync::Mutex, collections::HashMap};
use once_cell::sync::Lazy;static GLOBAL_DATA: Lazy<Mutex<HashMap<i32, String>>> = Lazy::new(|| {
let mut m = HashMap::new();
m.insert(13, "Spica".to_string());
m.insert(74, "Hoyten".to_string());
Mutex::new(m)
});fn main() {
println!("{:?}", GLOBAL_DATA.lock().unwrap());
}
Note that variables holding Lazy
are declared static
, not const
. This is important: using const
instead can compile, but it doesn't work properly.