Структура Once Cell
pub struct OnceCell<T> { /* private fields */ }
sync.Потокобезопасная ячейка, в которую можно записать значение только один раз.
OnceCell обычно используется для глобальных переменных, которые нужно инициализировать при первом использовании, но не требуется изменять в дальнейшем. OnceCell в Tokio позволяет выполнять процедуру инициализации асинхронно.
Примеры
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>
pub fn new() -> Self
Создает новый пустой экземпляр OnceCell.
pub const fn const_new() -> Self
Создает новый пустой экземпляр OnceCell.
Эквивалентно OnceCell::new, за исключением того, что его можно использовать в статических переменных.
При использовании нестабильной функции tracing экземпляр OnceCell, созданный с помощью const_new, не будет инструментирован. Поэтому он не будет виден в 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
Создает новый OnceCell, содержащий заданное значение, если оно указано.
Если Option — это None, данный вызов эквивалентен OnceCell::new.
pub const fn const_new_with(value: T) -> Self
Создает новый OnceCell, содержащий заданное значение.
Пример
При использовании нестабильной функции tracing экземпляр OnceCell, созданный с помощью const_new_with, не будет инструментирован. Поэтому он не будет виден в 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
Возвращает true, если OnceCell в данный момент содержит значение, и false в противном случае.
pub fn get(&self) -> Option<&T>
Возвращает ссылку на значение, хранящееся в данный момент в OnceCell, или None, если OnceCell пуст.
pub fn get_mut(&mut self) -> Option<&mut T>
Возвращает изменяемую ссылку на значение, хранящееся в данный момент в OnceCell, или None, если OnceCell пуст.
Поскольку этот вызов получает изменяемое заимствование OnceCell, значение внутри OnceCell можно безопасно изменять — изменяемое заимствование статически гарантирует отсутствие других ссылок.
pub fn set(&self, value: T) -> Result<(), SetError<T>>
Устанавливает для OnceCell заданное значение, если OnceCell пуст.
Если OnceCell уже содержит значение, этот вызов завершится ошибкой SetError::AlreadyInitializedError.
Если OnceCell пуст, но другая задача в данный момент пытается установить значение, этот вызов завершится ошибкой SetError::InitializingError.
pub async fn get_or_init<F, Fut>(&self, f: F) -> &T
Возвращает текущее значение из OnceCell или инициализирует его с помощью заданной асинхронной операции.
Если другая задача в данный момент инициализирует OnceCell, этот вызов дождется ее завершения, а затем вернет полученное ею значение.
Если предоставленная операция отменяется или вызывает панику, попытка инициализации отменяется. Если другие задачи ожидают инициализации значения, одна из них начнет новую попытку инициализации.
Это приведет к взаимной блокировке, если f попытается рекурсивно инициализировать ячейку.
pub async fn get_or_try_init<E, F, Fut>(&self, f: F) -> Result<&T, E>
Возвращает текущее значение в OnceCell или инициализирует его с помощью указанной асинхронной операции.
Если другая задача в данный момент инициализирует OnceCell, этот вызов дождётся завершения другой задачи, а затем вернёт значение, полученное в результате её работы.
Если указанная операция возвращает ошибку, отменяется или вызывает панику, попытка инициализации отменяется. Если другие задачи ожидают инициализации значения, одна из них начнёт новую попытку его инициализации.
Это приведёт к взаимной блокировке, если f попытается рекурсивно инициализировать ячейку.
pub fn into_inner(self) -> Option<T>
Извлекает значение из ячейки, уничтожая её в процессе. Возвращает None, если ячейка пуста.
Реализации трейтов
impl<T: Clone> Clone for OnceCell<T>
fn clone_from(&mut self, source: &Self)
source. Подробнее
impl<T: Eq> Eq for OnceCell<T>
impl<T: Send> Send for OnceCell<T>
impl<T: Sync + Send> Sync for OnceCell<T>
Автоматические реализации трейтов
impl<T> !Freeze for OnceCell<T>
impl<T> !RefUnwindSafe for OnceCell<T>
impl<T> !UnwindSafe for OnceCell<T>
impl<T> Unpin for OnceCell<T>where T: Unpin,
impl<T> UnsafeUnpin for OnceCell<T>where T: UnsafeUnpin,
Общие реализации
impl<T> BorrowMut<T> for Twhere T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
impl<T> CloneToUninit for Twhere T: Clone,
unsafe fn clone_to_uninit(&self, dest: *mut u8)
clone_to_uninit)
impl<T> Instrument for T
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
impl<T> ToOwned for Twhere T: Clone,
type Owned = T
fn to_owned(&self) -> T
fn clone_into(&self, target: &mut T)
impl<T> WithSubscriber for T
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
Subscriber к этому типу и возвращает обёртку WithDispatch. Подробнее
MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/sync/struct.OnceCell.html