dyn Trait 动态分发
学习目标
- 理解动态分发 vs 静态分发
- 掌握
dyn Trait 用法
- 理解 vtable
核心概念
静态分发 vs 动态分发
fn print_static(item: &impl std::fmt::Display) {
println!("{}", item);
}
fn print_dynamic(item: &dyn std::fmt::Display) {
println!("{}", item);
}
trait 对象
trait Animal {
fn speak(&self) -> String;
}
struct Dog;
struct Cat;
impl Animal for Dog {
fn speak(&self) -> String { "汪汪".to_string() }
}
impl Animal for Cat {
fn speak(&self) -> String { "喵喵".to_string() }
}
fn main() {
let animals: Vec<Box<dyn Animal>> = vec![
Box::new(Dog),
Box::new(Cat),
];
for animal in &animals {
println!("{}", animal.speak());
}
}
对象安全
trait Cloneable {
fn clone(&self) -> Self;
}
trait Drawable {
fn draw(&self);
}
dyn 与生命周期
fn create() -> &'static dyn std::fmt::Display {
&42
}
fn process(item: &dyn std::fmt::Display) {
println!("{}", item);
}
fn create_box() -> Box<dyn std::fmt::Display> {
Box::new(42)
}
小结
| 概念 | 说明 |
|---|
&dyn Trait | trait 引用(动态分发) |
Box<dyn Trait> | trait 对象(堆分配) |
| vtable | 虚函数表,运行时查找方法 |
| 对象安全 | 不能返回 Self 或有泛型 |
| 性能 | 动态分发有间接调用开销 |