pub struct OnceCell<T> { /* private fields */ }Expand description
A single-threaded async cell initialized at most once.
The first caller to get_or_init runs the initializer.
Concurrent callers wait for that initializer and then receive the same
reference.
§Differences from other once cells
Initializer futures are local to one runtime thread and may be !Send,
unlike tokio::sync::OnceCell on Tokio’s multithreaded runtime.
std::sync::OnceLock is synchronous and blocks threads; this type awaits
local async initialization without atomics.
§Examples
use std::cell::{Cell, RefCell};
use std::rc::Rc;
use runite::sync::OnceCell;
let cell = Rc::new(OnceCell::new());
let init_count = Rc::new(Cell::new(0));
let observed = Rc::new(RefCell::new(Vec::new()));
for _ in 0..2 {
runite::spawn({
let cell = Rc::clone(&cell);
let init_count = Rc::clone(&init_count);
let observed = Rc::clone(&observed);
async move {
let value = cell
.get_or_init(|| {
let init_count = Rc::clone(&init_count);
async move {
init_count.set(init_count.get() + 1);
runite::yield_now().await;
42
}
})
.await;
observed.borrow_mut().push(*value);
}
});
}
runite::run();
assert_eq!(init_count.get(), 1);
assert_eq!(&*observed.borrow(), &[42, 42]);
assert_eq!(cell.get(), Some(&42));Implementations§
Source§impl<T> OnceCell<T>
impl<T> OnceCell<T>
Sourcepub fn get(&self) -> Option<&T>
pub fn get(&self) -> Option<&T>
Returns the initialized value, if any.
Returns None while the cell is empty or while an asynchronous
initializer is still running. If an initializer is cancelled or panics,
the cell returns to the empty state and get() continues to return
None until another initializer completes.
Sourcepub async fn get_or_init<F, Fut>(&self, f: F) -> &T
pub async fn get_or_init<F, Fut>(&self, f: F) -> &T
Returns the cell value, initializing it with f if needed.
Only one caller runs an initializer at a time. Other callers that arrive while initialization is in progress wait until the value is ready.
§Cancellation and panics
If the initializer future is dropped before completing (for example, the
awaiting task is aborted) or panics, the cell is reset to its empty state
and a waiting caller is woken to retry initialization with its own f.
The cell never becomes permanently stuck because an initializer did not
finish.