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)) }
302 // Just like for `Cell<T>` this isn't needed, but results in nicer error messages.
303 #[unstable(feature = "once_cell", issue = "74465")]
304 impl<T> !Sync for OnceCell<T> {}