【发布时间】:2019-09-20 11:50:29
【问题描述】:
我知道PhantomData 旨在消耗数据类型定义中的生命周期或类型参数,否则这些参数将不会被使用。我最近查看了Rust std lib 中Rc 的定义,并注意到它似乎使用了PhantomData,但看起来T 在兄弟字段ptr 中被用作NonNull<RcBox<T>>。文档说 NonNull 是 "*mut T but non-zero and covariant." 并继续使用以下语句进一步扩展该定义:
与
*mut T不同,NonNull<T>在 T 上是协变的。如果这对您的用例不正确,您应该在您的类型中包含一些PhantomData以提供不变性,例如PhantomData<Cell<T>>或PhantomData<&'a mut T>。
因此,它是否需要方差或更多是因为NonNull 实际上是一个原始指针,并且需要PhantomData 才能像this answer seems to imply 一样消耗省略的生命周期?
【问题讨论】:
-
什么省略了生命周期?没有可以忽略的生命周期。
-
啊,对了,因为没有明确的生命周期,
T的边界,任何类型的引用,以及原始指针,我们都没有提到生命周期,但这是否意味着PhantomData那么是为子类型问题提供的吗?我引用的后面的句子确实继续说“通常这不是必需的;协方差对于大多数安全抽象都是正确的,例如 Box、Rc、Arc、Vec 和 LinkedList。” iiuc 这意味着提供幻像类型会使外壳类型在T上保持不变,但随后Rc使用它,这句话暗示它在T上是协变的? -
Rc并不总是有PhantomData字段。这是引入它的提交:github.com/rust-lang/rust/commit/… -
提交消息引用了this conversation,但这似乎很老了,并不能完全解释为什么这样做。
-
我猜它与删除逻辑有关,与生命周期或子类型无关。我认为,@PeterHall 链接到的提交消息支持了我的猜测,并表明它与
Shared和NonNull之间的区别有关(替换了Shared)。
标签: rust