SuperAPI AI Directory

rust-zero-cost

Coding & development

View repository

Updated 10-15 22:15

About this skill

Generics vs Trait Object

Feature Generics (static dispatch) trait object (dynamic dispatch)
Performance Zero overhead vtable lookup
Code size May bloat Smaller
Compile time Longer Shorter
Flexibility Type must be known Determined at runtime
Heterogeneous collections Not supported Vec<Box<dyn Trait>>

When to use generics

// 类型在编译时已知
fn process<T: Processor>(item: T) {
    item.process();
}

// Returns the same type fn create_processor() -> impl Processor { // Returns a concrete type }

// Multiple type parameters fn combine<A: Display, B: Display>(a: A, b: B) -> String { format!("{} and {}", a, b) }



## 何时用 trait object

```rust
// 运行时决定类型
trait Plugin {
    fn run(&self);
}

struct PluginManager {
    plugins: Vec<Box<dyn Plugin>>,
}

// 异构集合
let handlers: Vec<Box<dyn Handler>> = vec![
    Box::new(HttpHandler),
    Box::new(GrpcHandler),
];

Object safety rules

// ❌ 不是对象安全的
trait Bad {
    fn create(&self) -> Self;  // 返回 Self
    fn method(&self, x: Self);  // 参数有 Self
}

// ✅ 对象安全
trait Good {
    fn name(&self) -> &str;
}

impl Trait vs dyn Trait

// impl Trait:返回具体类型(静态分发)
fn create_processor() -> impl Processor {
    HttpProcessor
}

// dyn Trait:返回 trait object(动态分发)
fn create_processor() -> Box<dyn Processor> {
    Box::new(HttpProcessor)
}

Performance impact

// 泛型:每个类型生成一份代码
fn process<T: Trait>(item: T) {
    item.method();
}
// 编译后:
// fn process_Http(item: Http) { ... }
// fn process_Ftp(item: Ftp) { ... }

// trait object:单一路径
fn process(item: &dyn Trait) {
    item.method();  // 通过 vtable 调用
}

Common errors

Error Cause Solution
E0277 Missing trait bound Add T: Trait
E0038 trait object unsafe Check object safety rules
E0308 Type mismatch Unify types or use generics
E0599 Implementation not found Implement the trait or check the bounds

Optimization strategies

  1. Use generics for hot code - Eliminates dynamic dispatch overhead
  2. Use dyn for plugin systems - Flexibility first
  3. Use generics for small collections - Avoid Box allocation
  4. Use dyn for large collections - Reduce code bloat