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
- Use generics for hot code - Eliminates dynamic dispatch overhead
- Use dyn for plugin systems - Flexibility first
- Use generics for small collections - Avoid Box allocation
- Use dyn for large collections - Reduce code bloat