m04-zero-cost
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseZero-Cost Abstraction
零成本抽象
Layer 1: Language Mechanics
第一层:语言机制
Core Question
核心问题
Do we need compile-time or runtime polymorphism?
Before choosing between generics and trait objects:
- Is the type known at compile time?
- Is a heterogeneous collection needed?
- What's the performance priority?
我们需要编译时多态还是运行时多态?
在选择泛型和Trait对象之前,请考虑:
- 类型是否在编译时已知?
- 是否需要异构集合?
- 性能优先级是什么?
Error → Design Question
错误 → 设计问题
| 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约束" | 这个抽象的层级是否合适? |
| E0308 | "修复类型" | 类型应该统一还是保持不同? |
| E0599 | "导入Trait" | 这个Trait是合适的抽象吗? |
| E0038 | "使对象安全" | 我们真的需要动态分发吗? |
Thinking Prompt
思考提示
Before adding trait bounds:
-
What abstraction is needed?
- Same behavior, different types → trait
- Different behavior, same type → enum
- No abstraction needed → concrete type
-
When is type known?
- Compile time → generics (static dispatch)
- Runtime → trait objects (dynamic dispatch)
-
What's the trade-off priority?
- Performance → generics
- Compile time → trait objects
- Flexibility → depends
在添加Trait约束之前:
-
需要什么样的抽象?
- 行为相同、类型不同 → Trait
- 行为不同、类型相同 → 枚举(enum)
- 不需要抽象 → 具体类型
-
类型何时确定?
- 编译时 → 泛型(静态分发)
- 运行时 → Trait对象(动态分发)
-
权衡优先级是什么?
- 性能 → 泛型
- 编译时间 → Trait对象
- 灵活性 → 视情况而定
Trace Up ↑
向上追溯 ↑
When type system fights back:
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? |
当类型系统发出警告时:
E0277(Trait约束不满足)
↑ 提问:抽象层级是否正确?
↑ 检查:m09-domain(正在抽象的是什么行为?)
↑ 检查:m05-type-driven(是否应该使用newtype?)| 持续出现的错误 | 追溯至 | 问题 |
|---|---|---|
| 复杂Trait约束 | m09-domain | 这个抽象是否合适? |
| 对象安全问题 | m05-type-driven | 类型状态(typestate)能否提供帮助? |
| 类型爆炸 | m10-performance | 是否接受dyn的开销? |
Trace Down ↓
向下推导 ↓
From design to implementation:
"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>从设计到实现:
"需要对具有相同行为的类型进行抽象"
↓ 编译时已知类型 → impl Trait 或 泛型
↓ 运行时确定类型 → dyn Trait
"需要不同类型的集合"
↓ 封闭类型集合 → enum
↓ 开放类型集合 → Vec<Box<dyn Trait>>
"需要返回不同类型"
↓ 相同类型 → impl Trait
↓ 不同类型 → Box<dyn Trait>Quick Reference
快速参考
| Pattern | Dispatch | Code Size | Runtime Cost |
|---|---|---|---|
| Static | +bloat | Zero |
| Dynamic | Minimal | vtable lookup |
| Static | +bloat | Zero |
| Dynamic | Minimal | Allocation + vtable |
| 模式 | 分发方式 | 代码体积 | 运行时开销 |
|---|---|---|---|
| 静态 | 增大 | 零开销 |
| 动态 | 最小 | 虚表查找 |
| 静态 | 增大 | 零开销 |
| 动态 | 最小 | 内存分配 + 虚表查找 |
Syntax Comparison
语法对比
rust
// 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>) { } // ownedrust
// 静态分发 - 编译时已知类型
fn process(x: impl Display) { } // 参数位置
fn process<T: Display>(x: T) { } // 显式泛型
fn get() -> impl Display { } // 返回值位置
// 动态分发 - 运行时确定类型
fn process(x: &dyn Display) { } // 引用
fn process(x: Box<dyn Display>) { } // 所有权Error Code Reference
错误码参考
| 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 |
| 错误码 | 原因 | 快速修复 |
|---|---|---|
| E0277 | 类型未实现Trait | 添加实现或修改约束 |
| E0308 | 类型不匹配 | 检查泛型参数 |
| E0599 | 未找到方法 | 使用 |
| E0038 | Trait不支持对象安全 | 使用泛型或重新设计 |
Decision Guide
决策指南
| 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 |
| 场景 | 选择 | 原因 |
|---|---|---|
| 性能关键场景 | 泛型 | 零运行时开销 |
| 异构集合 | | 运行时支持不同类型 |
| 插件架构 | | 编译时未知类型 |
| 减少编译时间 | | 减少单态化操作 |
| 小型、已知类型集合 | | 无间接开销 |
Object Safety
对象安全
A trait is object-safe if it:
- Doesn't have bound
Self: Sized - Doesn't return
Self - Doesn't have generic methods
- Uses for non-object-safe methods
where Self: Sized
Trait满足以下条件时支持对象安全:
- 没有约束
Self: Sized - 不返回
Self - 没有泛型方法
- 对非对象安全的方法使用约束
where Self: Sized
Anti-Patterns
反模式
| 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 |
| 反模式 | 问题所在 | 更好的方案 |
|---|---|---|
| 一切都过度泛型化 | 编译时间长、复杂度高 | 尽可能使用具体类型 |
已知类型使用 | 不必要的间接开销 | 泛型 |
| 复杂Trait层级 | 难以理解 | 更简洁的设计 |
| 忽略对象安全 | 限制灵活性 | 若需要则提前规划dyn的使用 |
Related Skills
相关技能
| When | See |
|---|---|
| Type-driven design | m05-type-driven |
| Domain abstraction | m09-domain |
| Performance concerns | m10-performance |
| Send/Sync bounds | m07-concurrency |
| 场景 | 参考 |
|---|---|
| 类型驱动设计 | m05-type-driven |
| 领域抽象 | m09-domain |
| 性能相关问题 | m10-performance |
| Send/Sync约束 | m07-concurrency |