mirror of https://github.com/rust-lang/rust.git
Rollup merge of #77392 - Canop:option_insert, r=m-ou-se
add `insert` to `Option` This removes a cause of `unwrap` and code complexity. This allows replacing ``` option_value = Some(build()); option_value.as_mut().unwrap() ``` with ``` option_value.insert(build()) ``` It's also useful in contexts not requiring the mutability of the reference. Here's a typical cache example: ``` let checked_cache = cache.as_ref().filter(|e| e.is_valid()); let content = match checked_cache { Some(e) => &e.content, None => { cache = Some(compute_cache_entry()); // unwrap is OK because we just filled the option &cache.as_ref().unwrap().content } }; ``` It can be changed into ``` let checked_cache = cache.as_ref().filter(|e| e.is_valid()); let content = match checked_cache { Some(e) => &e.content, None => &cache.insert(compute_cache_entry()).content, }; ``` *(edited: I removed `insert_with`)*
This commit is contained in:
commit
d7c635b3a5
|
@ -562,6 +562,36 @@ impl<T> Option<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Inserts `value` into the option then returns a mutable reference to it.
|
||||
///
|
||||
/// If the option already contains a value, the old value is dropped.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(option_insert)]
|
||||
///
|
||||
/// let mut opt = None;
|
||||
/// let val = opt.insert(1);
|
||||
/// assert_eq!(*val, 1);
|
||||
/// assert_eq!(opt.unwrap(), 1);
|
||||
/// let val = opt.insert(2);
|
||||
/// assert_eq!(*val, 2);
|
||||
/// *val = 3;
|
||||
/// assert_eq!(opt.unwrap(), 3);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "option_insert", reason = "newly added", issue = "78271")]
|
||||
pub fn insert(&mut self, value: T) -> &mut T {
|
||||
*self = Some(value);
|
||||
|
||||
match self {
|
||||
Some(v) => v,
|
||||
// SAFETY: the code above just filled the option
|
||||
None => unsafe { hint::unreachable_unchecked() },
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Iterator constructors
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
@ -792,7 +822,7 @@ impl<T> Option<T> {
|
|||
// Entry-like operations to insert if None and return a reference
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Inserts `v` into the option if it is [`None`], then
|
||||
/// Inserts `value` into the option if it is [`None`], then
|
||||
/// returns a mutable reference to the contained value.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -811,12 +841,12 @@ impl<T> Option<T> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "option_entry", since = "1.20.0")]
|
||||
pub fn get_or_insert(&mut self, v: T) -> &mut T {
|
||||
self.get_or_insert_with(|| v)
|
||||
pub fn get_or_insert(&mut self, value: T) -> &mut T {
|
||||
self.get_or_insert_with(|| value)
|
||||
}
|
||||
|
||||
/// Inserts a value computed from `f` into the option if it is [`None`], then
|
||||
/// returns a mutable reference to the contained value.
|
||||
/// Inserts a value computed from `f` into the option if it is [`None`],
|
||||
/// then returns a mutable reference to the contained value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -839,8 +869,8 @@ impl<T> Option<T> {
|
|||
*self = Some(f());
|
||||
}
|
||||
|
||||
match *self {
|
||||
Some(ref mut v) => v,
|
||||
match self {
|
||||
Some(v) => v,
|
||||
// SAFETY: a `None` variant for `self` would have been replaced by a `Some`
|
||||
// variant in the code above.
|
||||
None => unsafe { hint::unreachable_unchecked() },
|
||||
|
|
Loading…
Reference in New Issue