解除引用Rc <vec <t>&gt; Rust中的困惑

时间:2018-02-28 10:49:33

标签: rust dereference

为什么以下代码有效?

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]);)一起工作。但是也无法理解它与双重引用有关。

2 个答案:

答案 0 :(得分:9)

RcVec都实现了Deref,其中deref - 方法是使用*调用的。

let c = vec![1, 2, 3, 4, 5];

创建一个Vec,其中包含vec! - 宏的给定元素。

let r = Rc::new(c);

从Vector创建Reference counted Object。 Vector被移入RC

println!("{:?}", (**r)[0]);

这个有点棘手:*r dereferences Rc,所以我们得到了底层的Vector。 *rc dereferences向量为sliceslice[0] indexes切片的第一个元素,它会产生第一个元素1println!最终打印出结果。

答案 1 :(得分:7)

一旦我们围绕表达式(**r)[0]构建函数原型,可能会更容易理解会发生什么:

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

Playground

Rc<T>,就像Rust中大多数智能容器的典型情况一样,实现Deref,以便它可以用作对底层值的普通引用。反过来,Vec<T>实现Deref,以便它可以用作切片(Target = [T])。显式解除引用*,执行两次后,按顺序应用两次转换。

当然,通常你不需要这样做,因为Vec也实现了Index运算符。