Rust 1.80 开始支持 std::sync::LazyLock
,可以用于替换 lazy_static
。
Rust 对 static
常量的编译时初始化有一些限制:只能使用常量表达式、const 函数来初始化,而不支持非 const 函数,复杂表达式的初始化。
lazy_static
宏提供了在运行时对 static 变量进行初始化的能力,而且支持复杂表达式、调用非 const 函数的初始化。
语法:
static ref
的 ref 是必须的,表示HOSTNAME
是一个引用,即将表达式的值绑定为一个引用而不是值本身。HOSTNAME
引用类型是'static
生命周期。
lazy_static! {
[pub] static ref NAME_1: TYPE_1 = EXPR_1;
[pub] static ref NAME_2: TYPE_2 = EXPR_2;
...
[pub] static ref NAME_N: TYPE_N = EXPR_N;
}
// 或者
lazy_static! {
/// This is an example for using doc comment attributes
static ref EXAMPLE: u8 = 42;
}
lazy_static!
实现了一个内部类型,它实现了Deref<TYPE>
, 该内部类型作为NAME
的类型;- 当第一次对 NAME 进行 deref 操作时,Deref 的实现会用 EXPR 初始化 NAME,然后后续每次再 deref 时复用第一次初始化的结果;《=== 延迟初始化
lazy_static! {
/// This is an example for using doc comment attributes
static ref EXAMPLE: u8 = 42;
}
use std::collections::HashMap;
lazy_static! {
static ref HASHMAP: HashMap<u32, &'static str> = {
let mut m = HashMap::new();
m.insert(0, "foo");
m.insert(1, "bar");
m.insert(2, "baz");
m
};
static ref COUNT: usize = HASHMAP.len();
static ref NUMBER: u32 = times_two(21);
}
fn times_two(n: u32) -> u32 { n * 2 }
fn main() {
println!("The map has {} entries.", *COUNT);
println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
println!("A expensive calculation on a static results in: {}.", *NUMBER);
}