1 use crate::cell::{Cell, OnceCell};
5 /// A value which is initialized on the first access.
10 /// #![feature(once_cell)]
12 /// use std::cell::LazyCell;
14 /// let lazy: LazyCell<i32> = LazyCell::new(|| {
15 /// println!("initializing");
18 /// println!("ready");
19 /// println!("{}", *lazy);
20 /// println!("{}", *lazy);
28 #[unstable(feature = "once_cell", issue = "74465")]
29 pub struct LazyCell<T, F = fn() -> T> {
31 init: Cell<Option<F>>,
34 impl<T, F> LazyCell<T, F> {
35 /// Creates a new lazy value with the given initializing function.
40 /// #![feature(once_cell)]
42 /// use std::cell::LazyCell;
44 /// let hello = "Hello, World!".to_string();
46 /// let lazy = LazyCell::new(|| hello.to_uppercase());
48 /// assert_eq!(&*lazy, "HELLO, WORLD!");
50 #[unstable(feature = "once_cell", issue = "74465")]
51 pub const fn new(init: F) -> LazyCell<T, F> {
52 LazyCell { cell: OnceCell::new(), init: Cell::new(Some(init)) }
56 impl<T, F: FnOnce() -> T> LazyCell<T, F> {
57 /// Forces the evaluation of this lazy value and returns a reference to
60 /// This is equivalent to the `Deref` impl, but is explicit.
65 /// #![feature(once_cell)]
67 /// use std::cell::LazyCell;
69 /// let lazy = LazyCell::new(|| 92);
71 /// assert_eq!(LazyCell::force(&lazy), &92);
72 /// assert_eq!(&*lazy, &92);
74 #[unstable(feature = "once_cell", issue = "74465")]
75 pub fn force(this: &LazyCell<T, F>) -> &T {
76 this.cell.get_or_init(|| match this.init.take() {
78 None => panic!("`Lazy` instance has previously been poisoned"),
83 #[unstable(feature = "once_cell", issue = "74465")]
84 impl<T, F: FnOnce() -> T> Deref for LazyCell<T, F> {
86 fn deref(&self) -> &T {
91 #[unstable(feature = "once_cell", issue = "74465")]
92 impl<T: Default> Default for LazyCell<T> {
93 /// Creates a new lazy value using `Default` as the initializing function.
94 fn default() -> LazyCell<T> {
95 LazyCell::new(T::default)
99 #[unstable(feature = "once_cell", issue = "74465")]
100 impl<T: fmt::Debug, F> fmt::Debug for LazyCell<T, F> {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()