Use Once for single-threaded one-time initialization and OnceLock for thread-safe initialization that returns a reference to the value. OnceLock is the modern, preferred choice for most use cases as it handles both single and multi-threaded scenarios safely.
use std::sync::OnceLock;
static CONFIG: OnceLock<String> = OnceLock::new();
fn get_config() -> &'static str {
CONFIG.get_or_init(|| {
// Expensive initialization runs exactly once
String::from("loaded configuration")
})
}