(I don't know what category this topic should be, so I leave it uncategorized)
Let's look into the source of Option::get_or_insert function.
pub fn get_or_insert(&mut self, value: T) -> &mut T {
if let None = *self {
*self = Some(value);
}
// SAFETY: a `None` variant for `self` would have been replaced by a `Some`
// variant in the code above.
unsafe { self.as_mut().unwrap_unchecked() }
}
This function judges an Option
is Some
or None
. If it is None
, give it a value, let it become a Some
. Then use unwrap_unchecked
to return the inner value, using unsafe code to avoid overhead.
How about if we can retain the variant information? Just like this:
pub fn get_or_insert(&mut self, value: T) -> &mut T {
let this: &mut Some = match self {
// Rule1: variant information can be provided by the pattern matching
// now `this`'s type is `&mut Option::Some`
this @ Some(_) => this,
// `_this`'s type is `&mut Option::None`
_this @ None => {
// Rule2: variant information can be provided
// by direct assignment as well
*self = Some(value);
// now `self`'s type becomes to `&mut Option::Some`,
// but only in the current scope
self
}
}
// `self`'s type is unchanged, still be `Option`
// return `Some`'s first value, just like tuple struct
&mut this.0
}
I believe this topic has been discussed many times. Can anybody bring me to the discussion place please?