Struct LazyCell

pub struct LazyCell<T, F = fn() -> T> { pub(in ::cell::lazy) state: UnsafeCell<State<T, F>> }

A value which is initialized on the first access.

For a thread-safe version of this struct, see std::sync::LazyLock.

Poisoning

If the initialization closure passed to LazyCell::new panics, the cell will be poisoned. Once the cell is poisoned, any threads that attempt to access this cell (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 LazyCell is unrecoverable. All future accesses of the cell from other threads will panic, whereas a type in std::sync::poison like std::sync::poison::Mutex allows recovery via PoisonError::into_inner().

Examples

use std::cell::LazyCell;

let lazy: LazyCell<i32> = LazyCell::new(|| {
    println!("initializing");
    92
});
println!("ready");
println!("{}", *lazy);
println!("{}", *lazy);

// Prints:
//   ready
//   initializing
//   92
//   92

Fields

state: UnsafeCell<State<T, F>>

Implementations

impl<T, F> LazyCell<T, F>

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

Returns a mutable reference to the value if initialized. Otherwise (if uninitialized or poisoned), returns None.

Examples

use std::cell::LazyCell;

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

assert_eq!(LazyCell::get_mut(&mut lazy), None);
let _ = LazyCell::force(&lazy);
*LazyCell::get_mut(&mut lazy).unwrap() = 44;
assert_eq!(*lazy, 44);
fn get(this: &LazyCell<T, F>) -> Option<&T>

Returns a reference to the value if initialized. Otherwise (if uninitialized or poisoned), returns None.

Examples

use std::cell::LazyCell;

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

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

impl<T, F: FnOnce() -> T> LazyCell<T, F>

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

Creates a new lazy value with the given initializing function.

Examples

use std::cell::LazyCell;

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

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

assert_eq!(&*lazy, "HELLO, WORLD!");
const fn into_inner(this: Self) -> Result<T, F>

Consumes this LazyCell returning the stored value.

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

Panics

Panics if the cell is poisoned.

Examples

#![feature(lazy_cell_into_inner)]

use std::cell::LazyCell;

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

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

assert_eq!(&*lazy, "HELLO, WORLD!");
assert_eq!(LazyCell::into_inner(lazy).ok(), Some("HELLO, WORLD!".to_string()));
fn force(this: &LazyCell<T, F>) -> &T

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

This is equivalent to the Deref impl, but is explicit.

Panics

If the initialization closure panics (the one that is passed to the new() method), the panic is propagated to the caller, and the cell becomes poisoned. This will cause all future accesses of the cell (via force() or a dereference) to panic.

Examples

use std::cell::LazyCell;

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

assert_eq!(LazyCell::force(&lazy), &92);
assert_eq!(&*lazy, &92);
fn force_mut(this: &mut LazyCell<T, F>) -> &mut T

Forces 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 cell becomes poisoned. This will cause all future accesses of the cell (via force() or a dereference) to panic.

Examples

use std::cell::LazyCell;

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

let p = LazyCell::force_mut(&mut lazy);
assert_eq!(*p, 92);
*p = 44;
assert_eq!(*lazy, 44);
unsafe fn really_init(this: &LazyCell<T, F>) -> &T

Safety

May only be called when the state is Uninit.

Trait Implementations

impl<T, F> From<T> for LazyCell<T, F>

fn from(value: T) -> Self

Constructs a LazyCell that starts already initialized with the provided value.

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

type Target = T;
fn deref(&self) -> &T

Panics

If the initialization closure panics (the one that is passed to the new() method), the panic is propagated to the caller, and the cell becomes poisoned. This will cause all future accesses of the cell (via force() or a dereference) to panic.

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

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

Panics

If the initialization closure panics (the one that is passed to the new() method), the panic is propagated to the caller, and the cell becomes poisoned. This will cause all future accesses of the cell (via force() or a dereference) to panic.

impl<T: Debug, F> Debug for LazyCell<T, F>

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

impl<T: Default> Default for LazyCell<T>

fn default() -> LazyCell<T>

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

Auto Trait Implementations

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

impl<T, F = fn() -> T> !RefUnwindSafe for LazyCell<T, F>

impl<T, F = fn() -> T> !Sync for LazyCell<T, F>

impl<T, F> Send for LazyCell<T, F> where UnsafeCell<State<T, F>>: Send,

impl<T, F> Unpin for LazyCell<T, F> where UnsafeCell<State<T, F>>: Unpin,

impl<T, F> UnsafeUnpin for LazyCell<T, F> where UnsafeCell<State<T, F>>: UnsafeUnpin,

impl<T, F> UnwindSafe for LazyCell<T, F> where UnsafeCell<State<T, F>>: UnwindSafe,

Blanket Implementations

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

type Target = T;

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

fn type_id(&self) -> TypeId

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

fn borrow(&self) -> &T

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

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

impl<T> From<T> for LazyCell<T, F>

fn from(t: T) -> T

Returns the argument unchanged.

impl<T> From<never> for LazyCell<T, F>

fn from(t: never) -> T

impl<T> SizeHint for LazyCell<T, F> where T: ?Sized,

fn lower_bound(&self) -> usize
fn upper_bound(&self) -> Option<usize>

impl<T> SizedTypeProperties for LazyCell<T, F>

impl<T, U> Into<U> for LazyCell<T, F> 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 LazyCell<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 LazyCell<T, F> where U: TryFrom<T>,

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