Z
ZHANK
编程在线教程Rust 教程Trait 对象与动态分发
泛型与 Trait

Trait 对象与动态分发

dyn Trait、Box<dyn Trait>、静态分发 vs 动态分发、对象安全

Trait 对象与动态分发

dyn Trait 实现运行时多态——类似 C++ 虚函数。Box<dyn Trait> 是最常见的 trait 对象形式。

学完本章你将: 掌握 dyn Trait、Box、静态 vs 动态分发。


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)
调用方式编译期单态化运行时虚表
性能最快(可内联)略有开销
二进制大小更大更小
适用具体类型异构集合