取消引用 Rc<Vec<T>> Rust 中的混淆

Dereferencing Rc<Vec<T>> confusion in Rust

为什么下面的代码有效?

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]);) 一起工作。但无法理解它也适用于双重取消引用。

两者,Rc and Vec implements Deref, whichs deref-方法是用 * 调用的。

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

创建一个 Vec with the given elements with the vec!-宏。

let r = Rc::new(c);

创建 Reference counted Object from the Vector. The Vector is moved into the RC.

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

这个有点棘手:*r dereferences the Rc, so we get the underlying Vector. *rc dereferences the Vector as a slice. slice[0] indexes 切片的第一个元素,结果是第一个元素 1println! 最终打印结果。

围绕表达式 (**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 运算符。