pub struct OnceCell<T> { /* 私有字段 */ }展开描述
只能写入一次的线程安全单元。
OnceCell 通常用于需要在首次使用时初始化一次但不需要进一步更改的全局变量。Tokio 中的 OnceCell 允许异步执行初始化过程。
§示例
use tokio::sync::OnceCell;
async fn some_computation() -> u32 {
1 + 1
}
static ONCE: OnceCell<u32> = OnceCell::const_new();
let result = ONCE.get_or_init(some_computation).await;
assert_eq!(*result, 2);编写用于访问值的包装方法通常很有用。
use tokio::sync::OnceCell;
static ONCE: OnceCell<u32> = OnceCell::const_new();
async fn get_global_integer() -> &'static u32 {
ONCE.get_or_init(|| async {
1 + 1
}).await
}
let result = get_global_integer().await;
assert_eq!(*result, 2);实现§
源代码§impl<T> OnceCell<T>
impl<T> OnceCell<T>
源代码pub const fn const_new() -> Self
pub const fn const_new() -> Self
创建一个新的空 OnceCell 实例。
等效于 OnceCell::new,但可以在静态变量中使用。
当使用 tracing 不稳定功能 时,使用 const_new 创建的 OnceCell 不会被检测。因此,它在 tokio-console 中不可见。如果需要,应改用 OnceCell::new 创建被检测的对象。
§示例
use tokio::sync::OnceCell;
static ONCE: OnceCell<u32> = OnceCell::const_new();
async fn get_global_integer() -> &'static u32 {
ONCE.get_or_init(|| async {
1 + 1
}).await
}
let result = get_global_integer().await;
assert_eq!(*result, 2);源代码pub fn new_with(value: Option<T>) -> Self
pub fn new_with(value: Option<T>) -> Self
创建一个新的 OnceCell,其中包含所提供的值(如果有)。
如果 Option 为 None,则等效于 OnceCell::new。
源代码pub const fn const_new_with(value: T) -> Self
pub const fn const_new_with(value: T) -> Self
创建一个包含所提供值的新 OnceCell。
§示例
当使用 tracing 不稳定功能 时,使用 const_new_with 创建的 OnceCell 不会被检测。因此,它在 tokio-console 中不可见。如果需要,应改用 OnceCell::new_with 创建被检测的对象。
use tokio::sync::OnceCell;
static ONCE: OnceCell<u32> = OnceCell::const_new_with(1);
async fn get_global_integer() -> &'static u32 {
ONCE.get_or_init(|| async {
1 + 1
}).await
}
let result = get_global_integer().await;
assert_eq!(*result, 1);源代码pub fn initialized(&self) -> bool
pub fn initialized(&self) -> bool
如果 OnceCell 当前包含值,则返回 true,否则返回 false。
源代码pub fn get_mut(&mut self) -> Option<&mut T>
pub fn get_mut(&mut self) -> Option<&mut T>
返回当前存储在 OnceCell 中的值的可变引用,如果 OnceCell 为空则返回 None。
由于此调用可变地借用 OnceCell,因此可以安全地变更 OnceCell 中的值——可变借用在静态上保证不存在其他引用。
源代码pub fn set(&self, value: T) -> Result<(), SetError<T>>
pub fn set(&self, value: T) -> Result<(), SetError<T>>
如果 OnceCell 为空,则将其值设置为给定值。
如果 OnceCell 已经有值,则此调用将失败并返回 SetError::AlreadyInitializedError。
如果 OnceCell 为空,但其他某个任务当前正在尝试设置值,则此调用将失败并返回 SetError::InitializingError。
源代码pub async fn get_or_init<F, Fut>(&self, f: F) -> &T
pub async fn get_or_init<F, Fut>(&self, f: F) -> &T
获取 OnceCell 中当前的值,或使用给定的异步操作进行初始化。
如果其他任务当前正在初始化 OnceCell,此调用将等待该其他任务完成,然后返回该其他任务产生的值。
如果所提供的操作被取消或发生 panic,则初始化尝试将被取消。如果有其他任务正在等待值的初始化,那么其中一个将开始另一次初始化该值的尝试。
如果 f 尝试递归初始化单元,则会发生死锁。
源代码pub async fn get_or_try_init<E, F, Fut>(&self, f: F) -> Result<&T, E>
pub async fn get_or_try_init<E, F, Fut>(&self, f: F) -> Result<&T, E>
获取 OnceCell 中当前的值,或使用给定的异步操作进行初始化。
如果其他任务当前正在初始化 OnceCell,此调用将等待该其他任务完成,然后返回该其他任务产生的值。
如果所提供的操作返回错误、被取消或发生 panic,则初始化尝试将被取消。如果有其他任务正在等待值被初始化,则其中一个任务将开始另一次初始化值的尝试。
如果 f 尝试递归初始化单元,则会发生死锁。
源代码pub fn into_inner(self) -> Option<T>
pub fn into_inner(self) -> Option<T>
从单元中取出值,此过程会销毁单元。如果单元为空,则返回 None。