Search code examples
rustdereference

Dereferencing Rc<Vec<T>> confusion in Rust


Why does the following code work?

use std::rc::Rc;
fn main () {
    let c = vec![1, 2, 3, 4, 5];
    let r = Rc::new(c);
    println!("{:?}", (**r)[0]);
}

I can understand it working with single deference (println!("{:?}", (*r)[0]);). But not able to understand it working with double-dereference too.


Solution

  • It might be easier to understand what happens once we build a function prototype around the expression (**r)[0]:

    fn foo<T, U>(r: T) -> i32
    where
        T: Deref<Target=U>,
        U: Deref<Target=[i32]>,
    {
        (**r)[0]
    }
    

    Playground

    Rc<T>, as is typical for most smart containers in Rust, implements Deref so that it can be used as an ordinary reference to the underlying value. In turn, Vec<T> implements Deref so that it can be used as a slice (Target = [T]). The explicit dereferencing *, when performed twice, applies the two conversions in sequence.

    Of course, usually you wouldn't need to do this, because Vec also implements the Index operator.