Trait 对象与动态分发
dyn Trait、Box<dyn Trait>、静态分发 vs 动态分发、对象安全
Trait 对象与动态分发
dyn Trait 实现运行时多态——类似 C++ 虚函数。Box<dyn Trait> 是最常见的 trait 对象形式。
学完本章你将: 掌握 dyn Trait、Box
Trait 对象
rust
trait Draw {
fn draw(&self);
}
struct Button { label: String }
impl Draw for Button {
fn draw(&self) { println!("[{}]", self.label); }
}
struct TextBox { text: String }
impl Draw for TextBox {
fn draw(&self) { println!("({})", self.text); }
}
fn main() {
// Vec<Box<dyn Draw>> —— 存放不同类型的 Draw 实现
let components: Vec<Box<dyn Draw>> = vec![
Box::new(Button { label: String::from("确定") }),
Box::new(TextBox { text: String::from("输入内容") }),
];
for comp in &components {
comp.draw(); // 动态分发
}
}
静态分发 vs 动态分发
rust
// 静态分发——泛型,编译期确定(零开销,但生成更多代码)
fn draw_static<T: Draw>(item: &T) {
item.draw();
}
// 动态分发——trait 对象,运行时确定(有虚函数开销,但代码更小)
fn draw_dynamic(item: &dyn Draw) {
item.draw();
}
| 静态(泛型) | 动态(dyn) | |
|---|---|---|
| 调用方式 | 编译期单态化 | 运行时虚表 |
| 性能 | 最快(可内联) | 略有开销 |
| 二进制大小 | 更大 | 更小 |
| 适用 | 具体类型 | 异构集合 |