为什么std :: rc :: Rc<>不是复制?

时间:2016-10-13 07:22:19

标签: rust smart-pointers

有人可以向我解释为什么Rc<>不是Copy

我正在编写使用大量共享指针的代码,并且不得不一直输入.clone()让我感到紧张。

在我看来,Rc<>应该只包含一个固定大小的指针,因此类型本身应该是Sized,因此Copy,对吗?

我错过了什么吗?

2 个答案:

答案 0 :(得分:28)

  

在我看来,Rc<>应该只包含一个固定大小的指针,因此类型本身应该是Sized,因此Copy,对吗?

这不是真的。 Rc R 参考 C 的缩写。这意味着该类型会跟踪有多少引用指向拥有的数据。这样,一旦引用计数达到0,我们就可以同时拥有多个所有者并安全地释放数据。

但我们如何保持参考计数器有效且最新?确切地说,每当创建新的引用/所有者以及删除引用/所有者时,我们都必须执行某些操作。具体来说,我们必须在前一种情况下增加计数器,在后一种情况下减少计数器。

通过实现析构函数的Rust等效项documentation来减少计数器。只要变量超出范围,就会执行此drop()函数 - 这完全符合我们的目标。

但我们什么时候做增量?你猜对了:clone()。根据定义,Drop表示只能通过复制位来复制类型:

  

只需复制位即可复制的类型(即memcpy)。

在我们的案例中并非如此,因为:是的,我们只是复制比特&#34;,但我们还做了额外的工作!我们确实需要增加参考计数器!

答案 1 :(得分:8)

如果类型实现Copysource),则无法实现Drop。由于Rc does implement it减少了引用计数,因此无法实现。

此外,Rc不仅仅是一个指针。它由Shared

组成
pub struct Rc<T: ?Sized> {
    ptr: Shared<RcBox<T>>,
}

反过来,它不仅仅是一个指针:

pub struct Shared<T: ?Sized> {
    pointer: NonZero<*const T>,
    _marker: PhantomData<T>,
}
需要

PhantomData来表达T的所有权:

  

此标记对方差没有影响,但是必须具备   了解我们逻辑上拥有T

     

详情请见:   https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data