Skip to main content

OnceLock

Struct OnceLock 

Source
pub struct OnceLock<T> { /* private fields */ }
Available on crate feature full and non-crate feature use_std only.
Expand description

A synchronization primitive which can nominally be written to only once.

This type is a thread-safe OnceCell, and can be used in statics. In many simple cases, you can use LazyLock<T, F> instead to get the benefits of this type with less effort: LazyLock<T, F> “looks like” &T because it initializes with F on deref! Where OnceLock shines is when LazyLock is too simple to support a given case, as LazyLock doesn’t allow additional inputs to its function after you call LazyLock::new(|| ...).

A OnceLock can be thought of as a safe abstraction over uninitialized data that becomes initialized once written.

Implementations§

Source§

impl<T> OnceLock<T>

Source

pub const fn new() -> Self

Creates a new uninitialized cell.

Source

pub fn get(&self) -> Option<&T>

Gets the reference to the underlying value.

Returns None if the cell is uninitialized, or being initialized. This method never blocks.

Source

pub fn get_mut(&mut self) -> Option<&mut T>

Gets the mutable reference to the underlying value.

Returns None if the cell is uninitialized.

This method never blocks. Since it borrows the OnceLock mutably, it is statically guaranteed that no active borrows to the OnceLock exist, including from other threads.

Source

pub fn get_or_init(&self, f: impl FnOnce() -> T) -> &T

Gets the contents of the cell, initializing it to f() if the cell was uninitialized.

Many threads may call get_or_init concurrently with different initializing functions, but it is guaranteed that only one function will be executed if the function doesn’t panic.

§Panics

If f() panics, the panic is propagated to the caller, and the cell remains uninitialized.

It is an error to reentrantly initialize the cell from f. The exact outcome is unspecified.

§Examples
use kernel_api::sync::OnceLock;

let cell = OnceLock::new();
let value = cell.get_or_init(|| 92);
assert_eq!(value, &92);
let value = cell.get_or_init(|| unreachable!());
assert_eq!(value, &92);

Trait Implementations§

Source§

impl<T: Debug> Debug for OnceLock<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Default for OnceLock<T>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<T: Send> Send for OnceLock<T>

Source§

impl<T: Send + Sync> Sync for OnceLock<T>

Auto Trait Implementations§

§

impl<T> !Freeze for OnceLock<T>

§

impl<T> !RefUnwindSafe for OnceLock<T>

§

impl<T> Unpin for OnceLock<T>
where UnsafeCell<MaybeUninit<T>>: Unpin,

§

impl<T> UnsafeUnpin for OnceLock<T>
where UnsafeCell<MaybeUninit<T>>: UnsafeUnpin,

§

impl<T> UnwindSafe for OnceLock<T>
where UnsafeCell<MaybeUninit<T>>: UnwindSafe,

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = !

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.