静态和动态调度

可以创建一个接受实现特定特征的对象的函数。

静态调度

fn generic_speak<T: Speak>(speaker: &T) {
    println!("{0}", speaker.speak());
}

fn main() {
    let person = Person {};
    let dog = Dog {};

    generic_speak(&person);
    generic_speak(&dog);
}

这里使用静态分派,这意味着 Rust 编译器将为 DogPerson 类型生成 generic_speak 函数的专用版本。在编译期间,这一代多态函数(或任何多态实体)的专用版本称为单形化

动态调度

fn generic_speak(speaker: &Speak) {
    println!("{0}", speaker.speak());
}

fn main() {
    let person = Person {};
    let dog = Dog {};

    generic_speak(&person as &Speak);
    generic_speak(&dog); // gets automatically coerced to &Speak
}

这里,编译后的二进制文件中只存在单个版本的 generic_speak,而 speak() 调用是在运行时使用 vtable 查找进行的。因此,使用动态分派可以加快编译速度并缩小编译后的二进制文件的大小,同时在运行时稍慢。

&SpeakBox<Speak> 类型的对象称为特征对象