How to clone an Option<Rc<_>> in Rust?
Asked Answered
U

2

15

Say I have an Option of Rc:

let x = Some(Rc::new(3));

If I need to make a clone, I can do:

let y = Some(Rc::clone(&x.unwrap()));

But it seems there's also a short cut:

let y = x.clone();

Are there any difference between these options? Or they are internally doing the same thing?

Ujiji answered 2/11, 2019 at 20:1 Comment(1)
Second one is much safer, first one may cause panic due to unwrap(), but yes if you think on happy path they do the sameBilocular
E
19

There's a generic implementation

impl<T: Clone> Clone for Option<T> {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            Some(x) => Some(x.clone()),
            None => None,
        }
    }
    // ...
}

So if x is Option<Rc<T>>, x.clone() will simply defer to the Clone implementation on Rc<T>.

Emia answered 2/11, 2019 at 20:11 Comment(3)
Ok, thanks for the answer. This makes sense. A following up question would be: is x.clone() equivalent to Rc::clone(&x) in this context?Ujiji
@Psidom It should be. Rc::clone(&x) is just the Clone implementation on Rc<T> (applied to a temporary reference - which is what x.clone() does too).Emia
The book talks a little bit about Rc::clone(&x) and x.clone() (in the last paragraph of that section). Simply put, the former one is just used to distinguish clones that increase the reference count from deep-copy ones.Excreta
H
2

Are there any difference between these options?

There is a difference when x is None.

With let y = Some(Rc::clone(&x.unwrap())); it will panic, while with let y = x.clone(); it will assign None to y.

When x is Some then there is no difference indeed.

So unless you explicitly want it to panic when x is None, the second option is recommended on top of being more concise.

Hurd answered 8/1 at 14:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.