Why is std::rc::Rc<> not Copy?

只愿长相守 提交于 2019-11-29 03:13:14
Lukas Kalbertodt

It seems to me that Rc<> should just consist of a pointer, which is a fixed size, so the type itself should be Sized and hence Copy, right?

This is not quite true. Rc is short for Reference Counted. This means that the type keeps track of how many references point to the owned data. That way we can have multiple owners at the same time and safely free the data, once the reference count reaches 0.


But how do we keep the reference counter valid and up to date? Exactly, we have to do something whenever a new reference/owner is created and whenever a reference/owner is deleted. Specifically, we have to increase the counter in the former case and decrease it in the latter.

The counter is decreased by implementing Drop, the Rust equivalent of a destructor. This drop() function is executed whenever a variable goes out of scope – perfect for our goal.

But when do we do the increment? You guessed it: in clone(). The Copy trait, by definition, says that a type can be duplicated just by copying bits:

Types that can be copied by simply copying bits (i.e. memcpy).

This is not true in our case, because: yes, we "just copy bits", but we also do additional work! We do need to increment our reference counter!

A type cannot implement Copy if it implements Drop (source). Since Rc does implement it to decrement its reference count, it is not possible.

In addition, Rc is not just a pointer. It consists of a Shared:

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

Which, in turn, is not only a pointer:

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

PhantomData is needed to express the ownership of T:

this marker has no consequences for variance, but is necessary for dropck to understand that we logically own a T.

For details, see: https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!