ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

幽灵数据

2022-03-29 15:04:24  阅读:180  来源: 互联网

标签:幽灵 const covariant PhantomData Vec marker invariant 数据


幽灵数据

在处理不安全代码时,我们经常会遇到这样的情况:类型或生命周期在逻辑上与结构相关,但实际上并不是字段的一部分。这种情况最常发生在生命周期上。例如,&'a [T]Iter(大约)定义如下:

 

struct Iter<'a, T: 'a> {
    ptr: *const T,
    end: *const T,
}

但是由于'a在结构体中是未使用的,所以它是无约束的。由于这在历史上造成的麻烦,在结构定义中,不受约束的生命周期和类型是禁止的,因此我们必须在主体中以某种方式引用这些类型,正确地做到这一点对于正确的变异性和丢弃检查是必要的。

我们使用PhantomData来做这个,它是一个特殊的标记类型。PhantomData不消耗空间,但为了静态分析的目的,模拟了一个给定类型的字段。这被认为比明确告诉类型系统你想要的变量类型更不容易出错,同时也提供了其他有用的东西,例如 drop check 需要的信息。

Iter 逻辑上包含一堆&'a T,所以这正是我们告诉PhantomData要模拟的。

 

use std::marker;

struct Iter<'a, T: 'a> {
    ptr: *const T,
    end: *const T,
    _marker: marker::PhantomData<&'a T>,
}

就是这样,生命周期将被限定,而你的迭代器将在'aT上进行协变。所有的东西都是有效的。

另一个重要的例子是 Vec,它(大约)定义如下:

 

struct Vec<T> {
    data: *const T, // *const 是可变异的!
    len: usize,
    cap: usize,
}

与前面的例子不同的是,看起来一切都和我们想的一样。Vec 的每个通用参数至少在一个字段中出现。很好,可以开始了!

不对,不是这样。

丢弃检查器将慷慨地确定Vec<T>不拥有任何 T 类型的值。这将反过来使它得出结论,它不需要担心 Vec 在其析构器中丢弃任何 T 来确定丢弃检查的合理性。这将反过来允许人们使用 Vec 的析构器来制造不健壮性。

为了告诉 dropck 我们确实拥有 T 类型的值,因此在我们丢弃时可能会丢弃一些 T,我们必须添加一个额外的PhantomData,正如这样:

 

use std::marker;

struct Vec<T> {
    data: *const T, // *const 是可变异的!
    len: usize,
    cap: usize,
    _marker: marker::PhantomData<T>,
}

拥有内存分配的原始指针是如此普遍的模式,以至于标准库为自己整了一个名为Unique<T>的类型:

  • 包装一个*const T,用于变异
  • 包括一个PhantomData<T>
  • 根据包含的 T 自动派生Send/Sync
  • 空指针的优化,将指针标记为NonZero

PhantomData模式表

下面是一个关于所有可以使用PhantomData的神奇方式的表格:
(covariant:协变,invariant:不变,contravariant:逆变)

Phantom type'aT
PhantomData<T> - covariant (with drop check)
PhantomData<&'a T> covariant covariant
PhantomData<&'a mut T> covariant invariant
PhantomData<*const T> - covariant
PhantomData<*mut T> - invariant
PhantomData<fn(T)> - contravariant
PhantomData<fn() -> T> - covariant
PhantomData<fn(T) -> T> - invariant
PhantomData<Cell<&'a ()>> invariant -

标签:幽灵,const,covariant,PhantomData,Vec,marker,invariant,数据
来源: https://www.cnblogs.com/horysk/p/16071776.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有