Rust之PhantomData

PhantomData是一个零大小类型的标记结构体。

作用:

  1. 并不使用的类型;
  2. 型变;
  3. 标记拥有关系;
  4. 自动trait实现(send/sync);

并不使用的类型

生命周期

struct Slice<'a, T> {
    start: *const T,
    end: *const T,
}

然而,因为'a在结构体中未使用,所以它是无界的。在结构定义中禁止无限生命周期和类型。

修改如下:

use std::marker;

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

类型

pub struct RetryableSendCh> {
    ch: C,
    name: &'static str,
    marker: PhantomData,
}

标记拥有关系

struct Vec {
    data: *const T, // *const for variance!
    len: usize,
    cap: usize,
}

原生指针不具有所有权语义,drop检查器将认为Vec不具有类型T的任何值。这将反过来使得它不需要担心Vec在其析构函数中丢弃任何T。但是有可能T被提前释放。为了drop检查器认为vec一定拥有了T的数据,修改如下:

use std::marker;

struct Vec {
    data: *const T, // *const for variance!
    len: usize,
    cap: usize,
    _marker: marker::PhantomData,
}

型变

  • 不变

如果不能将一个类型替换为另一个类型,那么这个类型就称之为:不变

  • 逆变

可以由其基类替换。

  • 协变

可以由其派生类型替换。

PhantomData模式表

这是一张PhantomData可以使用的所有方法的表格:

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

(*)如果逆变被废除,这将是不变的。

你可能感兴趣的:(Rust之PhantomData)