协变类型

Covariant Types

根据 Rustonomicon,&mut TT 上是不变的。当 &mut (str, str) 不是 &mut (T, T) 的子类型时,如何编译以下代码?

fn swap<T: Copy>(pair: &mut (T, T)) {
    let temp = pair.0;
    pair.0 = pair.1;
    pair.1 = temp;
}

fn main() {
    let mut pair = ("left", "right");
    swap(&mut pair);
    println!("{:?}", pair);
}

相关章节为here

Rustonomicon 暗示只有当 VT 的子类型时,您才能在 f(V) 上调用 f: (T) -> U。 (第 4 个代码块,示例是 evil_feeder(pet: &mut Animal) 被调用 &mut Cat)。如果不是子类型,上面的例子如何编译?

它可以编译,因为你没有使用&mut (str, str)。你拥有的是 &mut (&'static str, &'static str)。这是因为字符串文字是对 read-only 内存的引用,实际字符串存储在可执行文件中。

它可以满足函数的要求,因为即使 str 没有实现 Copy,所有不可变引用都实现了 Copy.

变体主要与类型强制有关,仅次于泛型。

另见 https://ehsanmkermani.com/2019/03/16/variance-in-rust-an-intuitive-explanation/, https://doc.rust-lang.org/reference/subtyping.html, and https://doc.rust-lang.org/reference/type-coercions.html#coercion-types