Struct LazyLock

1.80.0 · Source
pub struct LazyLock<T, F = fn() -> T> { /* private fields */ }
Expand description

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.

§Examples

Initialize static variables with LazyLock.

use std::sync::LazyLock;

// Note: static items do not call [`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: LazyLock<String> = LazyLock::new(|| {
    // M3 Ultra takes about 16 million years in --release config
    another_crate::great_question()
});

// The `String` is built, stored in the `LazyLock`, and returned as `&String`.
let _ = &*DEEP_THOUGHT;

Initialize fields with LazyLock.

use std::sync::LazyLock;

#[derive(Debug)]
struct UseCellLock {
    number: LazyLock<u32>,
}
fn main() {
    let lock: LazyLock<u32> = LazyLock::new(|| 0u32);

    let data = UseCellLock { number: lock };
    println!("{}", *data.number);
}

Implementations§

Source§

impl<T, F> LazyLock<T, F>
where F: FnOnce() -> T,

1.80.0 (const: 1.80.0) · Source

pub const fn new(f: F) -> LazyLock<T, F>

Creates a new lazy value with the given initializing function.

§Examples
use std::sync::LazyLock;

let hello = "Hello, World!".to_string();

let lazy = LazyLock::new(|| hello.to_uppercase());

assert_eq!(&*lazy, "HELLO, WORLD!");
Source

pub fn into_inner(this: LazyLock<T, F>) -> Result<T, F>

🔬This is a nightly-only experimental API. (lazy_cell_into_inner)

Consumes this LazyLock returning the stored value.

Returns Ok(value) if Lazy is initialized and Err(f) otherwise.

§Examples
#![feature(lazy_cell_into_inner)]

use std::sync::LazyLock;

let hello = "Hello, World!".to_string();

let lazy = LazyLock::new(|| hello.to_uppercase());

assert_eq!(&*lazy, "HELLO, WORLD!");
assert_eq!(LazyLock::into_inner(lazy).ok(), Some("HELLO, WORLD!".to_string()));
Source

pub fn force_mut(this: &mut LazyLock<T, F>) -> &mut T

🔬This is a nightly-only experimental API. (lazy_get)

Forces the evaluation of this lazy value and returns a mutable reference to the result.

§Examples
#![feature(lazy_get)]
use std::sync::LazyLock;

let mut lazy = LazyLock::new(|| 92);

let p = LazyLock::force_mut(&mut lazy);
assert_eq!(*p, 92);
*p = 44;
assert_eq!(*lazy, 44);
1.80.0 · Source

pub fn force(this: &LazyLock<T, F>) -> &T

Forces the evaluation of this lazy value and returns a reference to result. This is equivalent to the Deref impl, but is explicit.

This method will block the calling thread if another initialization routine is currently running.

§Examples
use std::sync::LazyLock;

let lazy = LazyLock::new(|| 92);

assert_eq!(LazyLock::force(&lazy), &92);
assert_eq!(&*lazy, &92);
Source§

impl<T, F> LazyLock<T, F>

Source

pub fn get_mut(this: &mut LazyLock<T, F>) -> Option<&mut T>

🔬This is a nightly-only experimental API. (lazy_get)

Returns a mutable reference to the value if initialized, or None if not.

§Examples
#![feature(lazy_get)]

use std::sync::LazyLock;

let mut lazy = LazyLock::new(|| 92);

assert_eq!(LazyLock::get_mut(&mut lazy), None);
let _ = LazyLock::force(&lazy);
*LazyLock::get_mut(&mut lazy).unwrap() = 44;
assert_eq!(*lazy, 44);
Source

pub fn get(this: &LazyLock<T, F>) -> Option<&T>

🔬This is a nightly-only experimental API. (lazy_get)

Returns a reference to the value if initialized, or None if not.

§Examples
#![feature(lazy_get)]

use std::sync::LazyLock;

let lazy = LazyLock::new(|| 92);

assert_eq!(LazyLock::get(&lazy), None);
let _ = LazyLock::force(&lazy);
assert_eq!(LazyLock::get(&lazy), Some(&92));

Trait Implementations§

1.80.0 · Source§

impl<T, F> Debug for LazyLock<T, F>
where T: Debug,

Source§

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

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

impl<T> Default for LazyLock<T>
where T: Default,

Source§

fn default() -> LazyLock<T>

Creates a new lazy value using Default as the initializing function.

1.80.0 · Source§

impl<T, F> Deref for LazyLock<T, F>
where F: FnOnce() -> T,

Source§

fn deref(&self) -> &T

Dereferences the value.

This method will block the calling thread if another initialization routine is currently running.

Source§

type Target = T

The resulting type after dereferencing.
1.89.0 · Source§

impl<T, F> DerefMut for LazyLock<T, F>
where F: FnOnce() -> T,

Source§

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

Mutably dereferences the value.
1.80.0 · Source§

impl<T, F> Drop for LazyLock<T, F>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
1.80.0 · Source§

impl<T, F> RefUnwindSafe for LazyLock<T, F>

1.80.0 · Source§

impl<T, F> Sync for LazyLock<T, F>
where T: Sync + Send, F: Send,

1.80.0 · Source§

impl<T, F> UnwindSafe for LazyLock<T, F>
where T: UnwindSafe, F: UnwindSafe,

Auto Trait Implementations§

§

impl<T, F = fn() -> T> !Freeze for LazyLock<T, F>

§

impl<T, F> Send for LazyLock<T, F>
where T: Send, F: Send,

§

impl<T, F> Unpin for LazyLock<T, F>
where T: Unpin, F: Unpin,

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<U> As for U

Source§

fn as_<T>(self) -> T
where T: CastFrom<U>,

Casts self to type T. The semantics of numeric casting with the as operator are followed, so <T as As>::as_::<U> can be used in the same way as T as U for numeric conversions. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T, U> ContextualTryInto<U> for T
where U: ContextualTryFrom<T>,

Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromBits<T> for T

Source§

fn from_bits(other: T) -> T

Convert other to Self, preserving bitwise representation
Source§

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

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<X, Y> LabelledResolve<Y> for X
where Y: LabelledResolveFrom<X>,

Source§

fn labelled_resolve( self, resolver: &impl LabelResolver<<Y as LabelledResolvable>::ResolverOutput>, ) -> Y

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<X, Y> Resolve<Y> for X
where Y: ResolveFrom<X>,

Source§

fn resolve(self) -> Y

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

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

Source§

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

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

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

Performs the conversion.