0%

Rust型变

型变

  • 型变(subtype)指根据原始类型子类型关系确定复杂类型子类型关系的规则。型变分为三种形式:
    • 协变(covariant)。保持子类型关系
    • 逆变(contravariant)。逆转子类型关系
    • 不变(invariant)。不保持也不逆转类型关系,即无关
  • Rust中只有生命周期有子类型关系,长类型是短类型的子类型
  • PhantomData<T>是一个零大小类型的标记结构体,也叫幻影类型,它扮演三个角色:
    • 型变
    • 标记拥有关系(drop)
    • 自动trait实现(Send和Sync)

几个重要的型变列表

  • &’a T在'aT上是协变的,对应*const T也是协变
  • &’a mut T在'a上是协变,但在T上是不变的
  • Fn(T)->UT上是不变,在U上是协变
  • Box<T>Vec<T>以及其他集合对于它们包含的类型来说是协变
  • UnsafeCell<T>Cell<T>RefCell<T>Mutex<T>以及其他内部可变类型在T上都是不变,对应* mut T也是不变
  • 对于结构退来说,如果包含的字段都是协变,则结构体是协变,否则为不变。对Phantomdata<T>类型来说,有以下规则:
    • PhantomData<T>,在T上是协变
    • PhantomData<&'a T>,在'aT上是协变
    • PhantomData<&'a mut T>,在'a上是协变,在T上是不变
    • PhantomData<*const T>,在T上是协变
    • PhantomData<*mut T>,在T上是不变
    • PhantomData<fn(T)>,在T上是逆变,如果以后修改语法,会成为不变
    • PhantomData<fn()->T>,在T上是协变
    • PhantomData<fn(T)->T>,在T上是不变
    • PhantomData<Cell<&'a()>>,在'a上是不变
  • 当协变不会引起未定义行为的时候,可以用协变,否则就保证该类型为不变或逆变