Lazy Initialization
Recipe | Crates | Categories |
---|---|---|
std | ||
once_cell | ||
lazy_static |
Two key libraries:
once_cell
: newer crate with more ergonomic API. Should be preferred for all new projects.lazy_static
: older crate. API is less convenient, but crate is stable and maintained.
The core functionality of once_cell
is now included in the standard library with the remaining parts on track to be stabilised in future.
std
OnceCell⮳ is a cell which can be written to only once.
The corresponding Sync version of OnceCell<T>
is OnceLock<T>
.
use std::cell::OnceCell; fn main() { let cell = OnceCell::new(); assert!(cell.get().is_none()); let value: &String = cell.get_or_init(|| "Hello, World!".to_string()); println!("{value}"); assert_eq!(value, "Hello, World!"); assert!(cell.get().is_some()); }
once_cell
once_cell
⮳ provides two cell-like types, unsync::OnceCell
and sync::OnceCell
. A OnceCell
might store arbitrary non-Copy types, can be assigned to at most once and provides direct access to the stored contents. The sync
flavor is thread-safe. once_cell
also has a once_cell::sync::Lazy
⮳ type, build on top of OnceCell
⮳:
use std::collections::HashMap; use std::sync::Mutex; use once_cell::sync::Lazy; // Must be static, not const 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()); }
lazy_static
fn main() { todo!(); }
[lazy_initialization: write, dedupe with global_static (P1)](https://github.com/john-cd/rust_howto/issues/411)