为什么以下代码有效?
use std::rc::Rc;
fn main () {
let c = vec![1, 2, 3, 4, 5];
let r = Rc::new(c);
println!("{:?}", (**r)[0]);
}
我可以理解它与单一的deference(println!("{:?}", (*r)[0]);
)一起工作。但是也无法理解它与双重引用一起工作。
一旦我们围绕表达式(**r)[0]
构建函数原型,可能更容易理解会发生什么:
fn foo<T, U>(r: T) -> i32
where
T: Deref<Target=U>,
U: Deref<Target=[i32]>,
{
(**r)[0]
}
Rc<T>
,就像Rust中大多数智能容器的典型情况一样,实现了Deref
,因此它可以用作对底层值的普通引用。反过来,Vec<T>
实施Deref
,以便它可以用作切片(Target = [T]
)。显式解除引用*
,执行两次时,按顺序应用两次转换。
当然,通常你不需要这样做,因为Vec
也实现了Index
运算符。
Rc和Vec都实现了Deref,其中deref
方法被称为*
。
let c = vec![1, 2, 3, 4, 5];
let r = Rc::new(c);
从Vector创建一个Reference counted Object。 Vector被移入RC。
println!("{:?}", (**r)[0]);
这个有点棘手:*r
dereferences Rc,所以我们得到了底层的Vector。 *rc
dereferences作为slice的矢量。 slice[0]
indexes切片的第一个元素,这导致第一个元素1
。 println!
终于打印出结果了。