在前文中我們分析了使用lazy_static來構(gòu)造全局變量汁雷,典型用法如下:
#[macro_use]
extern crate lazy_static;
use std::collections::HashMap;
lazy_static! {
static ref VEC:Vec<u8> = vec![0x19u8, 0x21u8];
static ref MAP: HashMap<u32, String> = {
let mut map = HashMap::new();
map.insert(2021, "year".to_owned());
map
};
static ref PAGE:u32 = init_val(2018);
}
fn init_val(i: u32) -> u32 {
i * 2
}
fn main() {
println!("{:?}", *PAGE);
println!("{:?}", *VEC);
println!("{:?}", *MAP);
}
once_cell 提供了 unsync::OnceCell 和 sync::OnceCell 這兩種接口剂公,前者用于單線程错览,后者用于多線程琳骡,可用來存儲堆上的信息,并且具有最多只能賦值一次的特性。
提供的API如下:
fn set(&self, value: T) -> Result<(), T> { ... }
=> 安全的設(shè)置全局變量
fn get(&self) -> Option<&T> { ... }
=> 獲取已經(jīng)設(shè)置的全局變量
get_or_init(Fn)
=> 獲取全局變量令宿,為空則初始化
Lazy::new(Fn)
=> 延遲創(chuàng)建全局變量
典型用法如下:
use std::{sync::Mutex, collections::HashMap};
use once_cell::sync::Lazy;
use once_cell::sync::OnceCell;
static GLOBAL_DATA: Lazy<Mutex<HashMap<i32, String>>> = Lazy::new(|| {
let mut m = HashMap::new();
m.insert(13, "chain".to_string());
m.insert(74, "queue".to_string());
Mutex::new(m)
});
fn global_data() -> &'static Mutex<HashMap<i32, String>> {
static INSTANCE: OnceCell<Mutex<HashMap<i32, String>>> = OnceCell::new();
INSTANCE.get_or_init(|| {
let mut m = HashMap::new();
m.insert(13, "sky".to_string());
m.insert(74, "walker".to_string());
Mutex::new(m)
})
}
相比而言叼耙,once_cell沒有采用宏的方式實現(xiàn),代碼看起來更加干凈易懂粒没。