跳到主要内容

variance-phantomdata

方差(Variance)与 PhantomData、Drop 检查

方差速览

  • 协变(Covariant):T1 <: T2F<T1> <: F<T2>
  • 逆变(Contravariant):T1 <: T2F<T2> <: F<T1>
  • 不变(Invariant):无上述关系。

Rust 中常见:

  • &'a T'a 协变,对 T 协变;
  • &'a mut TT 不变(可变借用导致不变性);
  • Box<T>T 协变;Cell<T>/RefCell<T>/UnsafeCell<T>T 不变。

PhantomData 的作用

  • 向编译器声明“逻辑上拥有”某类型/生命周期,以影响方差/Drop 检查/自动 trait(Send/Sync)。
use std::marker::PhantomData;

struct MyVec<'a, T> {
ptr: *mut T,
len: usize,
_lt: PhantomData<&'a T>, // 告诉编译器:与 'a 相关,协变
}

错误示例:若遗漏 PhantomData,可能绕过借用检查或 Drop 检查导致悬垂。

Drop 检查(Drop Check)

  • Rust 在析构时会检查借用不越界;带生命周期参数的类型若在 Drop 中可能访问借用数据,需保证生命周期正确表达(常需 PhantomData)。

Send/Sync 与自动 trait

  • 自定义类型通过字段的自动 trait 组合决定是否 Send/Sync
  • 使用 PhantomData<*const T> 可标记为“不共享可变”(影响 Sync 推断)。