How to convert from Option<&T> to &Option<T> in Rust?

Viewed 66

For a non copy type, like HashMap<String, String> for example, how can I convert from Option<&T> to &Option (without cloning) ? (seems like I am looking for "the opposite" of .as_ref(), but as_deref() is not it)

1 Answers

You can't convert from Option<&T> to &Option<T> because that would mean moving the value out from behind the shared reference &T.

Rust's rules prevent that with good reason: there could be multiple shared references to an object, so moving the object would leave the other references dangling.

You can, however, move out of a mutable reference using std::mem::take, so you can convert an Option<&mut T> to &Option<T> like this:

    let h : HashMap<String,String> = HashMap::new();
    let mut o1 = Some(h);                       // Option<T>
    let o2 = o1.as_mut();                       // Option<&mut T>
    let o3 = &o2.map(std::mem::take);           // &Option<T>

Note that take replaces the argument with the default value of T, so you can only use it if T implemented Default. Other options are to use replace or swap.

Related