解除引用Rc > Rust的困惑

问题描述 投票:5回答:2

为什么以下代码有效?

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

rust dereference
2个回答
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运算符。


9
投票

RcVec都实现了Deref,其中deref方法被称为*

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

使用Vec-macro创建带有给定元素的vec!

let r = Rc::new(c);

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

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

这个有点棘手:*r dereferences Rc,所以我们得到了底层的Vector。 *rc dereferences作为slice的矢量。 slice[0] indexes切片的第一个元素,这导致第一个元素1println!终于打印出结果了。

© www.soinside.com 2019 - 2024. All rights reserved.