Struct LazyLock
pub struct LazyLock<T, F = fn() -> T> { pub(in ::sync::lazy_lock) once: Once, pub(in ::sync::lazy_lock) data: UnsafeCell<Data<T, F>> }
A value which is initialized on the first access.
This type is a thread-safe LazyCell, and can be used in statics.
Since initialization may be called from multiple threads, any
dereferencing call will block the calling thread if another
initialization routine is currently running.
Poisoning
If the initialization closure passed to LazyLock::new panics, the lock will be poisoned.
Once the lock is poisoned, any threads that attempt to access this lock (via a dereference
or via an explicit call to force()) will panic.
This concept is similar to that of poisoning in the std::sync::poison module. A key
difference, however, is that poisoning in LazyLock is unrecoverable. All future accesses of
the lock from other threads will panic, whereas a type in std::sync::poison like
std::sync::poison::Mutex allows recovery via PoisonError::into_inner().
Examples
Initialize static variables with LazyLock.
use LazyLock;
// Note: static items do not call [`Drop`](Drop) on program termination, so this won't be deallocated.
// this is fine, as the OS can deallocate the terminated program faster than we can free memory
// but tools like valgrind might report "memory leaks" as it isn't obvious this is intentional.
static DEEP_THOUGHT: = new;
// The `String` is built, stored in the `LazyLock`, and returned as `&String`.
let _ = &*DEEP_THOUGHT;
Initialize fields with LazyLock.
use LazyLock;
Fields
once: Oncedata: UnsafeCell<Data<T, F>>
Implementations
impl<T, F> LazyLock<T, F>
fn get_mut(this: &mut LazyLock<T, F>) -> Option<&mut T>Returns a mutable reference to the value if initialized. Otherwise (if uninitialized or poisoned), returns
None.Examples
use LazyLock; let mut lazy = new; assert_eq!; let _ = force; *get_mut.unwrap = 44; assert_eq!;fn get(this: &LazyLock<T, F>) -> Option<&T>Returns a reference to the value if initialized. Otherwise (if uninitialized or poisoned), returns
None.Examples
use LazyLock; let lazy = new; assert_eq!; let _ = force; assert_eq!;
impl<T, F: FnOnce() -> T> LazyLock<T, F>
const fn new(f: F) -> LazyLock<T, F>Creates a new lazy value with the given initializing function.
Examples
use LazyLock; let hello = "Hello, World!".to_string; let lazy = new; assert_eq!;fn into_inner(this: Self) -> Result<T, F>Consumes this
LazyLockreturning the stored value.Returns
Ok(value)ifLazyis initialized andErr(f)otherwise.Panics
Panics if the lock is poisoned.
Examples
use LazyLock; let hello = "Hello, World!".to_string; let lazy = new; assert_eq!; assert_eq!;fn force_mut(this: &mut LazyLock<T, F>) -> &mut TForces the evaluation of this lazy value and returns a mutable reference to the result.
Panics
If the initialization closure panics (the one that is passed to the
new()method), the panic is propagated to the caller, and the lock becomes poisoned. This will cause all future accesses of the lock (viaforce()or a dereference) to panic.Examples
use LazyLock; let mut lazy = new; let p = force_mut; assert_eq!; *p = 44; assert_eq!;fn force(this: &LazyLock<T, F>) -> &TForces the evaluation of this lazy value and returns a reference to result. This is equivalent to the
Derefimpl, but is explicit.This method will block the calling thread if another initialization routine is currently running.
Panics
If the initialization closure panics (the one that is passed to the
new()method), the panic is propagated to the caller, and the lock becomes poisoned. This will cause all future accesses of the lock (viaforce()or a dereference) to panic.Examples
use LazyLock; let lazy = new; assert_eq!; assert_eq!;
Trait Implementations
impl<T, F> Drop for LazyLock<T, F>
fn drop(&mut self)
impl<T, F> From<T> for LazyLock<T, F>
fn from(value: T) -> SelfConstructs a
LazyLockthat starts already initialized with the provided value.
impl<T, F: FnOnce() -> T> Deref for LazyLock<T, F>
type Target = T;fn deref(&self) -> &TDereferences the value.
This method will block the calling thread if another initialization routine is currently running.
Panics
If the initialization closure panics (the one that is passed to the
new()method), the panic is propagated to the caller, and the lock becomes poisoned. This will cause all future accesses of the lock (viaforce()or a dereference) to panic.
impl<T, F: FnOnce() -> T> DerefMut for LazyLock<T, F>
impl<T: Debug, F> Debug for LazyLock<T, F>
fn fmt(&self, f: &mut Formatter<'_>) -> Result
impl<T: Default> Default for LazyLock<T>
fn default() -> LazyLock<T>Creates a new lazy value using
Defaultas the initializing function.
impl<T: RefUnwindSafe + UnwindSafe, F: UnwindSafe> RefUnwindSafe for LazyLock<T, F>
impl<T: Sync + Send, F: Send> Sync for LazyLock<T, F>
impl<T: UnwindSafe, F: UnwindSafe> UnwindSafe for LazyLock<T, F>
Auto Trait Implementations
impl<T, F = fn() -> T> !Freeze for LazyLock<T, F>
impl<T, F> Send for LazyLock<T, F>
where
UnsafeCell<Data<T, F>>: Send,
impl<T, F> Unpin for LazyLock<T, F>
where
UnsafeCell<Data<T, F>>: Unpin,
impl<T, F> UnsafeUnpin for LazyLock<T, F>
where
UnsafeCell<Data<T, F>>: UnsafeUnpin,
Blanket Implementations
impl<P, T> Receiver for LazyLock<T, F>
where
P: Deref<Target = T> + ?Sized,
T: ?Sized,
type Target = T;
impl<T> Any for LazyLock<T, F>
where
T: 'static + ?Sized,
fn type_id(&self) -> TypeId
impl<T> Borrow<T> for LazyLock<T, F>
where
T: ?Sized,
fn borrow(&self) -> &T
impl<T> BorrowMut<T> for LazyLock<T, F>
where
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
impl<T> From<T> for LazyLock<T, F>
fn from(t: T) -> TReturns the argument unchanged.
impl<T> From<never> for LazyLock<T, F>
fn from(t: never) -> T
impl<T> SizeHint for LazyLock<T, F>
where
T: ?Sized,
fn lower_bound(&self) -> usizefn upper_bound(&self) -> Option<usize>
impl<T> SizedTypeProperties for LazyLock<T, F>
impl<T, U> Into<U> for LazyLock<T, F>
where
U: From<T>,
fn into(self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses to do.
impl<T, U> TryFrom<U> for LazyLock<T, F>
where
U: Into<T>,
type Error = Infallible;fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto<U> for LazyLock<T, F>
where
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error;fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>