1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
use crate::ops::Deref;
use crate::{fmt, mem};

use super::UnsafeCell;

enum State<T, F> {
    Uninit(F),
    Init(T),
    Poisoned,
}

/// 在首次访问时初始化的值。
///
/// 有关此结构体的线程安全版本,请参见 [`std::sync::LazyLock`]。
///
/// [`std::sync::LazyLock`]: ../../std/sync/struct.LazyLock.html
///
/// # Examples
///
/// ```
/// #![feature(lazy_cell)]
///
/// use std::cell::LazyCell;
///
/// let lazy: LazyCell<i32> = LazyCell::new(|| {
///     println!("initializing");
///     92
/// });
/// println!("ready");
/// println!("{}", *lazy);
/// println!("{}", *lazy);
///
/// // Prints:
/// //   准备初始化
/////
/// //   92
/// //   92
/// ```
#[unstable(feature = "lazy_cell", issue = "109736")]
pub struct LazyCell<T, F = fn() -> T> {
    state: UnsafeCell<State<T, F>>,
}

impl<T, F: FnOnce() -> T> LazyCell<T, F> {
    /// 使用给定的初始化函数创建一个新的惰性值。
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(lazy_cell)]
    ///
    /// use std::cell::LazyCell;
    ///
    /// let hello = "Hello, World!".to_string();
    ///
    /// let lazy = LazyCell::new(|| hello.to_uppercase());
    ///
    /// assert_eq!(&*lazy, "HELLO, WORLD!");
    /// ```
    #[inline]
    #[unstable(feature = "lazy_cell", issue = "109736")]
    pub const fn new(f: F) -> LazyCell<T, F> {
        LazyCell { state: UnsafeCell::new(State::Uninit(f)) }
    }

    /// 使用此 `LazyCell` 返回存储的值。
    ///
    /// 如果 `Lazy` 已初始化,则返回 `Ok(value)`,否则返回 `Err(f)`。
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(lazy_cell)]
    /// #![feature(lazy_cell_consume)]
    ///
    /// 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()));
    /// ```
    #[unstable(feature = "lazy_cell_consume", issue = "109736")]
    pub fn into_inner(this: Self) -> Result<T, F> {
        match this.state.into_inner() {
            State::Init(data) => Ok(data),
            State::Uninit(f) => Err(f),
            State::Poisoned => panic!("LazyCell instance has previously been poisoned"),
        }
    }

    /// 强制对此延迟值求值,并向结果返回引用。
    ///
    ///
    /// 这等效于 `Deref` impl,但是是显式的。
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(lazy_cell)]
    ///
    /// use std::cell::LazyCell;
    ///
    /// let lazy = LazyCell::new(|| 92);
    ///
    /// assert_eq!(LazyCell::force(&lazy), &92);
    /// assert_eq!(&*lazy, &92);
    /// ```
    #[inline]
    #[unstable(feature = "lazy_cell", issue = "109736")]
    pub fn force(this: &LazyCell<T, F>) -> &T {
        // SAFETY:
        // 这会使对数据的任何可变引用无效。
        // 生成的引用要么一直存在到 `this` 的引用结束 (在初始化的情况下),要么在 `really_init` 中失效 (在未初始化的情况下; `really_init` 将创建并返回一个新的引用)。
        //
        //
        let state = unsafe { &*this.state.get() };
        match state {
            State::Init(data) => data,
            // SAFETY: 状态未初始化。
            State::Uninit(_) => unsafe { LazyCell::really_init(this) },
            State::Poisoned => panic!("LazyCell has previously been poisoned"),
        }
    }

    /// # Safety
    /// 只能在状态为 `Uninit` 时调用。
    #[cold]
    unsafe fn really_init(this: &LazyCell<T, F>) -> &T {
        // SAFETY:
        // 该函数只有在状态未初始化时才会被调用,所以对 `state` 的引用不能存在,除了 `force` 中的引用,在这里失效,不再访问。
        //
        //
        let state = unsafe { &mut *this.state.get() };
        // 暂时将状态标记为中毒。
        // 这可以防止重入访问并在封包 panic 时正确地使 cell 中毒。
        let State::Uninit(f) = mem::replace(state, State::Poisoned) else { unreachable!() };

        let data = f();

        // SAFETY:
        // 如果关闭包通过重入互锁之类的方式访问了 cell,但是捕获了状态中毒导致的 panic,那么 `state` 的可变借用就会失效,所以我们需要在这里通过 `UnsafeCell` 指针。
        // 状态只能在此时中毒,所以使用 `write` 跳过 `State` 的析构函数应该有助于优化器。
        //
        //
        //
        //
        unsafe { this.state.get().write(State::Init(data)) };

        // SAFETY:
        // 之前的引用被上面的 `write` 调用失效了,所以做一个新的状态共享引用代替。
        //
        let state = unsafe { &*this.state.get() };
        let State::Init(data) = state else { unreachable!() };
        data
    }
}

impl<T, F> LazyCell<T, F> {
    #[inline]
    fn get(&self) -> Option<&T> {
        // SAFETY:
        // 这与 `force` 中的原因相同: 一旦状态被初始化,它就不会再次被可变地访问,所以这个引用将在对 `self` 的引用期间保持有效。
        //
        //
        let state = unsafe { &*self.state.get() };
        match state {
            State::Init(data) => Some(data),
            _ => None,
        }
    }
}

#[unstable(feature = "lazy_cell", issue = "109736")]
impl<T, F: FnOnce() -> T> Deref for LazyCell<T, F> {
    type Target = T;
    #[inline]
    fn deref(&self) -> &T {
        LazyCell::force(self)
    }
}

#[unstable(feature = "lazy_cell", issue = "109736")]
impl<T: Default> Default for LazyCell<T> {
    /// 使用 `Default` 作为初始化函数创建一个新的惰性值。
    #[inline]
    fn default() -> LazyCell<T> {
        LazyCell::new(T::default)
    }
}

#[unstable(feature = "lazy_cell", issue = "109736")]
impl<T: fmt::Debug, F> fmt::Debug for LazyCell<T, F> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut d = f.debug_tuple("LazyCell");
        match self.get() {
            Some(data) => d.field(data),
            None => d.field(&format_args!("<uninit>")),
        };
        d.finish()
    }
}