pub struct LazyLock<T, F = fn() -> T> { /* private fields */ }
std
only.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;
// n.b. 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,
impl<T, F> LazyLock<T, F>where
F: FnOnce() -> T,
1.80.0 (const: 1.80.0) · Sourcepub const fn new(f: F) -> LazyLock<T, F>
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!");
Sourcepub fn into_inner(this: LazyLock<T, F>) -> Result<T, F> ⓘ
🔬This is a nightly-only experimental API. (lazy_cell_into_inner
)
pub fn into_inner(this: LazyLock<T, F>) -> Result<T, F> ⓘ
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()));
Sourcepub fn force_mut(this: &mut LazyLock<T, F>) -> &mut T
🔬This is a nightly-only experimental API. (lazy_get
)
pub fn force_mut(this: &mut LazyLock<T, F>) -> &mut T
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 · Sourcepub fn force(this: &LazyLock<T, F>) -> &T
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>
impl<T, F> LazyLock<T, F>
Sourcepub fn get_mut(this: &mut LazyLock<T, F>) -> Option<&mut T> ⓘ
🔬This is a nightly-only experimental API. (lazy_get
)
pub fn get_mut(this: &mut LazyLock<T, F>) -> Option<&mut T> ⓘ
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);
Sourcepub fn get(this: &LazyLock<T, F>) -> Option<&T> ⓘ
🔬This is a nightly-only experimental API. (lazy_get
)
pub fn get(this: &LazyLock<T, F>) -> Option<&T> ⓘ
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§
Source§impl<T: ConstDefault> ConstDefault for LazyLock<T>
impl<T: ConstDefault> ConstDefault for LazyLock<T>
impl<T, F> RefUnwindSafe for LazyLock<T, F>
impl<T, F> Sync for LazyLock<T, F>
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>
impl<T, F> Unpin for LazyLock<T, F>
Blanket Implementations§
§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
§type ArchivedMetadata = ()
type ArchivedMetadata = ()
§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> ByteSized for T
impl<T> ByteSized for T
Source§const BYTE_ALIGN: usize = _
const BYTE_ALIGN: usize = _
Source§fn byte_align(&self) -> usize ⓘ
fn byte_align(&self) -> usize ⓘ
Source§fn ptr_size_ratio(&self) -> [usize; 2]
fn ptr_size_ratio(&self) -> [usize; 2]
Source§impl<T, R> Chain<R> for Twhere
T: ?Sized,
impl<T, R> Chain<R> for Twhere
T: ?Sized,
Source§impl<T> ExtAny for T
impl<T> ExtAny for T
Source§fn as_any_mut(&mut self) -> &mut dyn Anywhere
Self: Sized,
fn as_any_mut(&mut self) -> &mut dyn Anywhere
Self: Sized,
Source§impl<T> ExtMem for Twhere
T: ?Sized,
impl<T> ExtMem for Twhere
T: ?Sized,
Source§const NEEDS_DROP: bool = _
const NEEDS_DROP: bool = _
Source§fn mem_align_of_val(&self) -> usize ⓘ
fn mem_align_of_val(&self) -> usize ⓘ
Source§fn mem_size_of_val(&self) -> usize ⓘ
fn mem_size_of_val(&self) -> usize ⓘ
Source§fn mem_needs_drop(&self) -> bool
fn mem_needs_drop(&self) -> bool
true
if dropping values of this type matters. Read moreSource§fn mem_forget(self)where
Self: Sized,
fn mem_forget(self)where
Self: Sized,
self
without running its destructor. Read moreSource§fn mem_replace(&mut self, other: Self) -> Selfwhere
Self: Sized,
fn mem_replace(&mut self, other: Self) -> Selfwhere
Self: Sized,
Source§unsafe fn mem_zeroed<T>() -> T
unsafe fn mem_zeroed<T>() -> T
unsafe_layout
only.T
represented by the all-zero byte-pattern. Read moreSource§unsafe fn mem_transmute_copy<Src, Dst>(src: &Src) -> Dst
unsafe fn mem_transmute_copy<Src, Dst>(src: &Src) -> Dst
unsafe_layout
only.T
represented by the all-zero byte-pattern. Read moreSource§fn mem_as_bytes(&self) -> &[u8] ⓘ
fn mem_as_bytes(&self) -> &[u8] ⓘ
unsafe_slice
only.§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> Hook for T
impl<T> Hook for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError> ⓘ
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError> ⓘ
§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out
indicating that a T
is niched.