为什么以下代码有效?
use std::rc::Rc;
fn main () {
let c = vec![1, 2, 3, 4, 5];
let r = Rc::new(c);
println!("{:?}", (**r)[0]);
}
我可以理解它与单一参与(println!("{:?}", (*r)[0]);
)一起工作。但是也无法理解它与双重引用有关。
答案 0 :(得分:9)
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!
最终打印出结果。
答案 1 :(得分:7)
一旦我们围绕表达式(**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
运算符。