once_cell
提供了unsync::OnceCell
和sync::OnceCell
这两种Cell(字面意思,前者用于单线程,后者用于多线程),用来存储堆上的信息,并且具有最多只能赋值一次的特性。API大概是:
impl<T> OnceCell<T> {
fn new() -> OnceCell<T> { ... }
fn set(&self, value: T) -> Result<(), T> { ... }
fn get(&self) -> Option<&T> { ... }
}
use std::{env, io};
use once_cell::sync::OnceCell;
#[derive(Debug)]
pub struct Logger {
// ...
}
static INSTANCE: OnceCell<Logger> = OnceCell::new();
impl Logger {
pub fn global() -> &'static Logger {
INSTANCE.get().expect("logger is not initialized")
}
fn from_cli(args: env::Args) -> Result<Logger, std::io::Error> {
// ...
}
}
fn main() {
let logger = Logger::from_cli(env::args()).unwrap();
INSTANCE.set(logger).unwrap();
// 之后就统一使用`Logger::global()`
}
包中提供了Lazy
,(也分sync和unsync版)可以起到类似之前提到过的lazy_static的作用——在第一次使用的时候产生一个动态的全局静态变量
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());
}
其中的好处就是不需要神奇的宏魔法了,这也是近期tokio
使用它取代了之前的lazy_static
的原因:https://github.com/tokio-rs/tokio/pull/3187
比起lazy_static
,我们还支持局部变量
use once_cell::unsync::Lazy;
fn main() {
let ctx = vec![1, 2, 3];
let thunk = Lazy::new(|| {
ctx.iter().sum::<i32>()
});
assert_eq!(*thunk, 6);
}
而且使用OnceCell还可以嵌入到结构体中
use std::{fs, path::PathBuf};
use once_cell::unsync::OnceCell;
struct Ctx {
config_path: PathBuf,
config: OnceCell<String>,
}
impl Ctx {
pub fn get_config(&self) -> Result<&str, std::io::Error> {
let cfg = self.config.get_or_try_init(|| {
fs::read_to_string(&self.config_path)
})?;
Ok(cfg.as_str())
}
}
因此可以用它来构建其它更复杂的东西!
那大家可能好奇它和lazy_static
究竟有什么区别。小结一下就是:
once_cell
更灵活易用,也没用宏魔法lazy_static
可以支持no_std不过Lazy
往上游提交pr也有很长时间了,有兴趣的可以去围观下https://github.com/rust-lang/rfcs/pull/2788
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有