pub struct OnceCell<T, B> { /* private fields */ }Expand description
An interior mutability cell type which allows synchronized one-time initialization and read-only access exclusively after initialization.
§Poisoning
A thread that panics in the course of executing its init function or
closure poisons the cell.
All subsequent accesses to a poisoned cell will propagate this and panic
themselves.
Implementations§
Source§impl<T, B> OnceCell<T, B>
impl<T, B> OnceCell<T, B>
Sourcepub fn into_inner(self) -> Option<T>
pub fn into_inner(self) -> Option<T>
Consumes self and returns a Some(T) if the OnceCell has
previously been successfully initialized or None otherwise.
§Panics
This method panics if the OnceCell has been poisoned.
§Examples
let uninit: OnceCell<i32> = OnceCell::uninit();
assert!(uninit.into_inner().is_none());
let once = OnceCell::uninit();
once.init_once(|| "initialized");
assert_eq!(once.into_inner(), Some("initialized"));Sourcepub fn is_initialized(&self) -> bool
pub fn is_initialized(&self) -> bool
Returns true if the OnceCell has been successfully initialized.
This method will never panic or block.
Sourcepub fn is_poisoned(&self) -> bool
pub fn is_poisoned(&self) -> bool
Returns true if the OnceCell has been poisoned during
initialization.
This method will never panic or block.
Once this method has returned true all other means of accessing the
OnceCell except for further calls to
is_initialized or
is_poisoned will panic.
Sourcepub fn try_get(&self) -> Result<&T, TryGetError>
pub fn try_get(&self) -> Result<&T, TryGetError>
Returns a reference to the OnceCell’s initialized inner state or
an Err.
This method will never blocks.
When this function returns with an Ok result, it is guaranteed that
some initialization closure has run and completed.
It is also guaranteed that any memory writes performed by the executed
closure can be reliably observed by other threads at this point (there
is a happens-before relation between the closure and code executing
after the return).
§Errors
This method fails if the OnceCell is either not initialized
(Uninit) or is currently being
initialized by some other thread
(WouldBlock).
§Panics
This method panics if the OnceCell has been poisoned.
Sourcepub unsafe fn get_unchecked(&self) -> &T
pub unsafe fn get_unchecked(&self) -> &T
Returns a reference to the inner value without checking whether the
OnceCell is actually initialized.
§Safety
The caller has to ensure that the cell has been successfully initialized, otherwise uninitialized memory will be read.
§Examples
This is one safe way to use this method, although
try_get is the better alternative:
use conquer_once::OnceCell;
// let cell = ...
let res = if cell.is_initialized() {
Some(unsafe { cell.get_unchecked() })
} else {
None
};
Source§impl<T, B: Unblock> OnceCell<T, B>
impl<T, B: Unblock> OnceCell<T, B>
Sourcepub fn try_init_once(
&self,
func: impl FnOnce() -> T,
) -> Result<(), TryInitError>
pub fn try_init_once( &self, func: impl FnOnce() -> T, ) -> Result<(), TryInitError>
Attempts to initialize the OnceCell with func if is is
uninitialized and returns Ok(()) only if func is successfully
executed.
This method will never block.
When this function returns with an Ok or
Err(AlreadyInit) result, it is guaranteed
that some initialization closure has run and completed (it may not be
the closure specified).
It is also guaranteed that any memory writes performed by the executed
closure can be reliably observed by other threads at this point (there
is a happens-before relation between the closure and code executing
after the return).
§Errors
This method fails, if the initialization of OnceCell has already
been completed previously, in which case an
AlreadyInit error is returned.
If another thread is concurrently in the process of initializing it and
this thread would have to block, a
WouldBlock error is returned.
§Panics
This method panics if the OnceCell has been poisoned.
§Examples
use conquer_once::{OnceCell, TryInitError};
let cell = OnceCell::uninit();
// .. in thread 1
let res = cell.try_init_once(|| {
1
});
assert!(res.is_ok());
// .. in thread 2
let res = cell.try_init_once(|| {
2
});
assert_eq!(res, Err(TryInitError::AlreadyInit));
Sourcepub fn try_get_or_init(
&self,
func: impl FnOnce() -> T,
) -> Result<&T, WouldBlockError>
pub fn try_get_or_init( &self, func: impl FnOnce() -> T, ) -> Result<&T, WouldBlockError>
Returns a reference to the OnceCell’s initialized inner state or
otherwise attempts to initialize it with func and return the result.
This method never blocks.
When this function returns with an Ok result, it is guaranteed that
some initialization closure has run and completed (it may not be the
closure specified).
It is also guaranteed that any memory writes performed by the executed
closure can be reliably observed by other threads at this point (there
is a happens-before relation between the closure and code executing
after the return).
§Errors
This method only fails if the calling thread would have to block in case
another thread is concurrently initializing the OnceCell.
§Panics
This method panics if the OnceCell has been poisoned.
Source§impl<T, B: Block> OnceCell<T, B>
impl<T, B: Block> OnceCell<T, B>
Sourcepub fn get(&self) -> Option<&T>
pub fn get(&self) -> Option<&T>
Returns a reference to the OnceCell’s initialized inner state or
None.
This method blocks if another thread has already begun initializing
the OnceCell concurrently.
See try_get for a non-blocking alternative.
When this function returns with Some, it is guaranteed that some
initialization closure has run and completed.
It is also guaranteed that any memory writes performed by the executed
closure can be reliably observed by other threads at this point (there
is a happens-before relation between the closure and code executing
after the return).
§Panics
This method panics if the OnceCell has been poisoned.
§Examples
use conquer_once::OnceCell;
let cell = OnceCell::uninit();
assert_eq!(cell.get(), None);
cell.init_once(|| {
1
});
assert_eq!(cell.get(), Some(&1));Sourcepub fn init_once(&self, func: impl FnOnce() -> T)
pub fn init_once(&self, func: impl FnOnce() -> T)
Attempts to initialize the OnceCell with func if it is
uninitialized.
This method blocks if another thread has already begun initializing
the OnceCell concurrently.
If the initialization of the OnceCell has already been
completed previously, this method returns early with minimal
overhead.
When this function returns, it is guaranteed that some initialization closure has run and completed (it may not be the closure specified). It is also guaranteed that any memory writes performed by the executed closure can be reliably observed by other threads at this point (there is a happens-before relation between the closure and code executing after the return).
§Panics
This method panics if the OnceCell has been poisoned.
§Examples
use conquer_once::OnceCell;
let cell = OnceCell::uninit();
cell.init_once(|| {
// expensive calculation
(0..1_000).map(|i| i * i).sum::<usize>()
});
cell.init_once(|| {
// any further or concurrent calls to `init_once` will do
// nothing and return immediately with almost no overhead.
});
Sourcepub fn get_or_init(&self, func: impl FnOnce() -> T) -> &T
pub fn get_or_init(&self, func: impl FnOnce() -> T) -> &T
Returns a reference to the OnceCell’s initialized inner state or
otherwise attempts to initialize it with func and return the result.
This method blocks if another thread has already begun
initializing the OnceCell concurrently.
See try_get_or_init for a non-blocking
alternative.
When this function returns, it is guaranteed that some initialization closure has run and completed (it may not be the closure specified). It is also guaranteed that any memory writes performed by the executed closure can be reliably observed by other threads at this point (there is a happens-before relation between the closure and code executing after the return).
§Panics
This method panics if the OnceCell has been poisoned.