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.
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]
}
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.