高级 trait

关联类型在 trait 定义中指定占位符类型

关联类型(associated types)是一个将类型占位符与 trait 相关联的方式,这样 trait 的方法签名中就可以使用这些占位符类型。 trait 的实现者会针对特定的实现在这个占位符类型置顶相应的具体类型。如此可以定义一个可以使用多种类型的 trait,知道实现此 trait 时 都无需知道这些类型具体时什么。

#![allow(unused)]
fn main() {
pub trait Iterator {
    type Item;
    fn next(&mut self) -> Option<Self::Item>;
}
}

Item 是一个占位符类型,同时 next 方法定义表明它返回 OptionSelf::Item 类型的值。这个 trait 的实现者会指定 Item 的具体类型。 然而不管实现者置顶何种类型,next 方法都会返回一个包含了此具体类型值的 Option。

关联类型看起来像一个类似泛型的概念,因为它允许定义一个函数而不指定其可以处理的类型。让我们通过在一个 Counter 结构体上实现 Iterator trait 的例子来检视其中的区别。这哥是现在宏指定了 Item 的类型为 u32:

默认泛型类型参数和运算符重载

<Rhs = Self> 这个语法叫做默认类型参数(default type parameters)。Rhs 是一个泛型类型参数(“right hand side”)的缩写。 它用于定义 add 方法中的 rhs 参数。如果实现 Add trait 时不指定 Rhs 的具体类型, Rhs 的类型将时默认的 Self 类型。也就是在骑上实现的 Add 类型。

扩展类型而不破坏现有代码。 在大部分用户都不需要的特定情况下进行自定义。

#![allow(unused)]
fn main() {
pub trait Add<Rhs = Self> {
    type Output;
    fn add(self, rhs: Rhs) -> Self::Output;
}
}

完全限定语法与消歧义:调用相同名称的方法

完全限定语法

trait Animal {
    fn baby_name() -> String;
}

struct Dog;

impl Dog {
    fn baby_name() -> String {
        String::from("Spot")
    }
}

impl Animal for Dog {
    fn baby_name() -> String {
        String::from("puppy")
    }
}

fn main() {
    println!("A baby dog is called a {}", Dog::baby_name());
    println!("A baby dog is called a {}", <Dog as Animal>::baby_name());
}

newtype 模式 用以在外部类型上实现外部trait

类型别名用来创建类型同义词

类型别名不是一新的单独的类型,完全被当作相同的类型对待。

fn main() {
    type Kilometers = i32;
    let x: i32 = 5;
    let y: Kilometers = 5;
    println!("x + y = {}", x + y);
}

动态大小类型和 Size trait

有时被称为 DSTunsized types ,这些类型允许我们处理只有在运行时才知道大小的类型。 为了处理 DST ,Rust 提供了 Sized trait 来决定一个类型的是否在编译时可知。这个 trait 自动为编译器在编译时就知道大小的类型实现。 Rust