Loading...
Loading...
CRITICAL: Use for generics, traits, zero-cost abstraction. Triggers: E0277, E0308, E0599, generic, trait, impl, dyn, where, monomorphization, static dispatch, dynamic dispatch, impl Trait, trait bound not satisfied, 泛型, 特征, 零成本抽象, 单态化
npx skill4agent add zhanghandong/rust-skills m04-zero-costLayer 1: Language Mechanics
| Error | Don't Just Say | Ask Instead |
|---|---|---|
| E0277 | "Add trait bound" | Is this abstraction at the right level? |
| E0308 | "Fix the type" | Should types be unified or distinct? |
| E0599 | "Import the trait" | Is the trait the right abstraction? |
| E0038 | "Make object-safe" | Do we really need dynamic dispatch? |
E0277 (trait bound not satisfied)
↑ Ask: Is the abstraction level correct?
↑ Check: m09-domain (what behavior is being abstracted?)
↑ Check: m05-type-driven (should use newtype?)| Persistent Error | Trace To | Question |
|---|---|---|
| Complex trait bounds | m09-domain | Is the abstraction right? |
| Object safety issues | m05-type-driven | Can typestate help? |
| Type explosion | m10-performance | Accept dyn overhead? |
"Need to abstract over types with same behavior"
↓ Types known at compile time → impl Trait or generics
↓ Types determined at runtime → dyn Trait
"Need collection of different types"
↓ Closed set → enum
↓ Open set → Vec<Box<dyn Trait>>
"Need to return different types"
↓ Same type → impl Trait
↓ Different types → Box<dyn Trait>| Pattern | Dispatch | Code Size | Runtime Cost |
|---|---|---|---|
| Static | +bloat | Zero |
| Dynamic | Minimal | vtable lookup |
| Static | +bloat | Zero |
| Dynamic | Minimal | Allocation + vtable |
// Static dispatch - type known at compile time
fn process(x: impl Display) { } // argument position
fn process<T: Display>(x: T) { } // explicit generic
fn get() -> impl Display { } // return position
// Dynamic dispatch - type determined at runtime
fn process(x: &dyn Display) { } // reference
fn process(x: Box<dyn Display>) { } // owned| Error | Cause | Quick Fix |
|---|---|---|
| E0277 | Type doesn't impl trait | Add impl or change bound |
| E0308 | Type mismatch | Check generic params |
| E0599 | No method found | Import trait with |
| E0038 | Trait not object-safe | Use generics or redesign |
| Scenario | Choose | Why |
|---|---|---|
| Performance critical | Generics | Zero runtime cost |
| Heterogeneous collection | | Different types at runtime |
| Plugin architecture | | Unknown types at compile |
| Reduce compile time | | Less monomorphization |
| Small, known type set | | No indirection |
Self: SizedSelfwhere Self: Sized| Anti-Pattern | Why Bad | Better |
|---|---|---|
| Over-generic everything | Compile time, complexity | Concrete types when possible |
| Unnecessary indirection | Generics |
| Complex trait hierarchies | Hard to understand | Simpler design |
| Ignore object safety | Limits flexibility | Plan for dyn if needed |
| When | See |
|---|---|
| Type-driven design | m05-type-driven |
| Domain abstraction | m09-domain |
| Performance concerns | m10-performance |
| Send/Sync bounds | m07-concurrency |