我知道
PhantomData
旨在消耗在数据类型定义中未被使用的生命周期或类型参数。最近我查看了Rust标准库中Rc
的定义,并注意到它似乎使用了PhantomData
,但是在同级字段ptr
中似乎使用了T
作为 NonNull<RcBox<T>>
。文档说NonNull
是"*mut T,但不为零且协变。"并进一步通过以下语句扩展了该定义:
因此,这是为了方差还是更多地因为与
*mut T
不同,NonNull<T>
在T上是协变的。如果这对你的用例不正确,则应在你的类型中包含一些PhantomData
来提供不变性,例如PhantomData<Cell<T>>
或PhantomData<&'a mut T>
。
NonNull
实际上是一个原始指针,并且需要使用PhantomData
来消耗省略的生命周期,正如这个答案似乎暗示的那样?
PhantomData
是为子类型化问题提供的?我引用的句子后面继续说道:“通常这不是必要的;协变对于大多数安全抽象是正确的,例如Box、Rc、Arc、Vec和LinkedList。”如果我理解正确,这意味着提供幻影类型使得容纳类型在T
上不变,但是Rc
使用它,这句话暗示它在T
上是协变的? - rjsRc
并不总是有PhantomData
字段。这是引入它的提交: https://github.com/rust-lang/rust/commit/60dc10492ccdf785678d475172f2653aae9606da#diff-da456bd3af6d94a9693e625ff7303113R286 - Peter HallShared
和NonNull
(替换了Shared
)之间的区别有关。 - trent