静态和动态调度
可以创建一个接受实现特定特征的对象的函数。
静态调度
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 编译器将为 Dog
和 Person
类型生成 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 查找进行的。因此,使用动态分派可以加快编译速度并缩小编译后的二进制文件的大小,同时在运行时稍慢。
&Speak
或 Box<Speak>
类型的对象称为特征对象。