1 use crate::cell
::UnsafeCell
;
5 /// A cell which can be written to only once.
7 /// Unlike [`RefCell`], a `OnceCell` only provides shared `&T` references to its value.
8 /// Unlike [`Cell`], a `OnceCell` doesn't require copying or replacing the value to access it.
10 /// For a thread-safe version of this struct, see [`std::sync::OnceLock`].
12 /// [`RefCell`]: crate::cell::RefCell
13 /// [`Cell`]: crate::cell::Cell
14 /// [`std::sync::OnceLock`]: ../../std/sync/struct.OnceLock.html
19 /// #![feature(once_cell)]
21 /// use std::cell::OnceCell;
23 /// let cell = OnceCell::new();
24 /// assert!(cell.get().is_none());
26 /// let value: &String = cell.get_or_init(|| {
27 /// "Hello, World!".to_string()
29 /// assert_eq!(value, "Hello, World!");
30 /// assert!(cell.get().is_some());
32 #[unstable(feature = "once_cell", issue = "74465")]
33 pub struct OnceCell
<T
> {
34 // Invariant: written to at most once.
35 inner
: UnsafeCell
<Option
<T
>>,
39 /// Creates a new empty cell.
42 #[unstable(feature = "once_cell", issue = "74465")]
43 pub const fn new() -> OnceCell
<T
> {
44 OnceCell { inner: UnsafeCell::new(None) }
47 /// Gets the reference to the underlying value.
49 /// Returns `None` if the cell is empty.
51 #[unstable(feature = "once_cell", issue = "74465")]
52 pub fn get(&self) -> Option
<&T
> {
53 // SAFETY: Safe due to `inner`'s invariant
54 unsafe { &*self.inner.get() }
.as_ref()
57 /// Gets the mutable reference to the underlying value.
59 /// Returns `None` if the cell is empty.
61 #[unstable(feature = "once_cell", issue = "74465")]
62 pub fn get_mut(&mut self) -> Option
<&mut T
> {
63 self.inner
.get_mut().as_mut()
66 /// Sets the contents of the cell to `value`.
70 /// This method returns `Ok(())` if the cell was empty and `Err(value)` if
76 /// #![feature(once_cell)]
78 /// use std::cell::OnceCell;
80 /// let cell = OnceCell::new();
81 /// assert!(cell.get().is_none());
83 /// assert_eq!(cell.set(92), Ok(()));
84 /// assert_eq!(cell.set(62), Err(62));
86 /// assert!(cell.get().is_some());
89 #[unstable(feature = "once_cell", issue = "74465")]
90 pub fn set(&self, value
: T
) -> Result
<(), T
> {
91 // SAFETY: Safe because we cannot have overlapping mutable borrows
92 let slot
= unsafe { &*self.inner.get() }
;
97 // SAFETY: This is the only place where we set the slot, no races
98 // due to reentrancy/concurrency are possible, and we've
99 // checked that slot is currently `None`, so this write
100 // maintains the `inner`'s invariant.
101 let slot
= unsafe { &mut *self.inner.get() }
;
106 /// Gets the contents of the cell, initializing it with `f`
107 /// if the cell was empty.
111 /// If `f` panics, the panic is propagated to the caller, and the cell
112 /// remains uninitialized.
114 /// It is an error to reentrantly initialize the cell from `f`. Doing
115 /// so results in a panic.
120 /// #![feature(once_cell)]
122 /// use std::cell::OnceCell;
124 /// let cell = OnceCell::new();
125 /// let value = cell.get_or_init(|| 92);
126 /// assert_eq!(value, &92);
127 /// let value = cell.get_or_init(|| unreachable!());
128 /// assert_eq!(value, &92);
131 #[unstable(feature = "once_cell", issue = "74465")]
132 pub fn get_or_init
<F
>(&self, f
: F
) -> &T
136 match self.get_or_try_init(|| Ok
::<T
, !>(f())) {
141 /// Gets the contents of the cell, initializing it with `f` if
142 /// the cell was empty. If the cell was empty and `f` failed, an
143 /// error is returned.
147 /// If `f` panics, the panic is propagated to the caller, and the cell
148 /// remains uninitialized.
150 /// It is an error to reentrantly initialize the cell from `f`. Doing
151 /// so results in a panic.
156 /// #![feature(once_cell)]
158 /// use std::cell::OnceCell;
160 /// let cell = OnceCell::new();
161 /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
162 /// assert!(cell.get().is_none());
163 /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
166 /// assert_eq!(value, Ok(&92));
167 /// assert_eq!(cell.get(), Some(&92))
169 #[unstable(feature = "once_cell", issue = "74465")]
170 pub fn get_or_try_init
<F
, E
>(&self, f
: F
) -> Result
<&T
, E
>
172 F
: FnOnce() -> Result
<T
, E
>,
174 if let Some(val
) = self.get() {
177 /// Avoid inlining the initialization closure into the common path that fetches
178 /// the already initialized value
180 fn outlined_call
<F
, T
, E
>(f
: F
) -> Result
<T
, E
>
182 F
: FnOnce() -> Result
<T
, E
>,
186 let val
= outlined_call(f
)?
;
187 // Note that *some* forms of reentrant initialization might lead to
188 // UB (see `reentrant_init` test). I believe that just removing this
189 // `assert`, while keeping `set/get` would be sound, but it seems
190 // better to panic, rather than to silently use an old value.
191 assert
!(self.set(val
).is_ok(), "reentrant init");
192 Ok(self.get().unwrap())
195 /// Consumes the cell, returning the wrapped value.
197 /// Returns `None` if the cell was empty.
202 /// #![feature(once_cell)]
204 /// use std::cell::OnceCell;
206 /// let cell: OnceCell<String> = OnceCell::new();
207 /// assert_eq!(cell.into_inner(), None);
209 /// let cell = OnceCell::new();
210 /// cell.set("hello".to_string()).unwrap();
211 /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
214 #[unstable(feature = "once_cell", issue = "74465")]
215 pub fn into_inner(self) -> Option
<T
> {
216 // Because `into_inner` takes `self` by value, the compiler statically verifies
217 // that it is not currently borrowed. So it is safe to move out `Option<T>`.
218 self.inner
.into_inner()
221 /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state.
223 /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized.
225 /// Safety is guaranteed by requiring a mutable reference.
230 /// #![feature(once_cell)]
232 /// use std::cell::OnceCell;
234 /// let mut cell: OnceCell<String> = OnceCell::new();
235 /// assert_eq!(cell.take(), None);
237 /// let mut cell = OnceCell::new();
238 /// cell.set("hello".to_string()).unwrap();
239 /// assert_eq!(cell.take(), Some("hello".to_string()));
240 /// assert_eq!(cell.get(), None);
243 #[unstable(feature = "once_cell", issue = "74465")]
244 pub fn take(&mut self) -> Option
<T
> {
245 mem
::take(self).into_inner()
249 #[unstable(feature = "once_cell", issue = "74465")]
250 impl<T
> Default
for OnceCell
<T
> {
252 fn default() -> Self {
257 #[unstable(feature = "once_cell", issue = "74465")]
258 impl<T
: fmt
::Debug
> fmt
::Debug
for OnceCell
<T
> {
259 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
261 Some(v
) => f
.debug_tuple("OnceCell").field(v
).finish(),
262 None
=> f
.write_str("OnceCell(Uninit)"),
267 #[unstable(feature = "once_cell", issue = "74465")]
268 impl<T
: Clone
> Clone
for OnceCell
<T
> {
270 fn clone(&self) -> OnceCell
<T
> {
271 let res
= OnceCell
::new();
272 if let Some(value
) = self.get() {
273 match res
.set(value
.clone()) {
275 Err(_
) => unreachable
!(),
282 #[unstable(feature = "once_cell", issue = "74465")]
283 impl<T
: PartialEq
> PartialEq
for OnceCell
<T
> {
285 fn eq(&self, other
: &Self) -> bool
{
286 self.get() == other
.get()
290 #[unstable(feature = "once_cell", issue = "74465")]
291 impl<T
: Eq
> Eq
for OnceCell
<T
> {}
293 #[unstable(feature = "once_cell", issue = "74465")]
294 impl<T
> const From
<T
> for OnceCell
<T
> {
295 /// Creates a new `OnceCell<T>` which already contains the given `value`.
297 fn from(value
: T
) -> Self {
298 OnceCell { inner: UnsafeCell::new(Some(value)) }