rust-refactor
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseRust Refactor Best Practices
Rust 重构最佳实践
Architectural refactoring guide for Rust applications. Contains 91 rules across 10 categories, prioritized by impact from critical (type safety, ownership) to incremental (iterator idioms).
这是一份Rust应用的架构重构指南,包含10个分类下的91条规则,按影响优先级排序,从关键(类型安全、所有权)到渐进式(迭代器惯用写法)依次排列。
When to Apply
适用场景
- Refactoring existing Rust codebases or planning large-scale restructuring
- Reviewing PRs for architectural issues and code smells
- Designing type-safe APIs with proper error handling
- Organizing Rust project structure with Cargo workspaces
- Improving module boundaries and visibility control
- Applying consistent naming conventions (RFC 430)
- Replacing stringly-typed APIs with strong types
- 重构现有Rust代码库或规划大规模架构调整
- 评审PR中的架构问题与代码坏味道
- 设计具备完善错误处理的类型安全API
- 使用Cargo工作区梳理Rust项目结构
- 优化模块边界与可见性控制
- 遵循统一的命名规范(RFC 430)
- 用强类型替代字符串类型API
Rule Categories
规则分类
| Category | Impact | Rules | Key Topics |
|---|---|---|---|
| Type Safety & Patterns | CRITICAL | 20 | Newtypes, typestate builders, PhantomData, enums, trait objects, associated types |
| Ownership & Borrowing | CRITICAL | 6 | Borrowing, Cow, lifetime elision, clone avoidance |
| Error Handling | HIGH | 15 | thiserror/anyhow, two-tier strategy, context, graceful degradation |
| API Design & Traits | HIGH | 6 | Sealed traits, extension traits, generic bounds, builder pattern |
| Project Organization | HIGH | 6 | Cargo workspaces, crate separation, feature grouping |
| Module & Visibility | MEDIUM-HIGH | 9 | Re-exports, visibility control, test co-location, module splitting |
| Naming Conventions | MEDIUM-HIGH | 13 | RFC 430, snake_case, PascalCase, predicates, unit suffixes |
| Conversion Traits | MEDIUM | 5 | From/Into, AsRef, TryFrom, Deref |
| Idiomatic Patterns | MEDIUM | 6 | Default, let-else, destructuring, match guards |
| Iterator & Collections | LOW-MEDIUM | 5 | Iterator methods, collect turbofish, filter_map |
| 分类 | 影响等级 | 规则数量 | 核心主题 |
|---|---|---|---|
| 类型安全与模式 | 关键 | 20 | Newtype、类型状态构建器、PhantomData、枚举、trait对象、关联类型 |
| 所有权与借用 | 关键 | 6 | 借用、Cow、生命周期省略、避免clone |
| 错误处理 | 高 | 15 | thiserror/anyhow、双层策略、上下文、优雅降级 |
| API设计与Trait | 高 | 6 | 密封trait、扩展trait、泛型约束、构建器模式 |
| 项目组织 | 高 | 6 | Cargo工作区、 crate 拆分、功能分组 |
| 模块与可见性 | 中-高 | 9 | 重导出、可见性控制、测试同目录存放、模块拆分 |
| 命名规范 | 中-高 | 13 | RFC 430、snake_case、PascalCase、断言、单位后缀 |
| 转换Trait | 中 | 5 | From/Into、AsRef、TryFrom、Deref |
| 惯用模式 | 中 | 6 | Default、let-else、解构、match守卫 |
| 迭代器与集合 | 低-中 | 5 | 迭代器方法、collect涡轮鱼语法、filter_map |
Quick Reference
快速参考
Critical patterns — get these right first:
- Use newtype patterns to prevent unit confusion and encode invariants
- Prefer borrowing over ownership in function parameters
- Use thiserror for library errors, anyhow for application errors
- Use typestate builders for compile-time required field enforcement
Common mistakes — avoid these anti-patterns:
- Stringly-typed APIs instead of strong types
- Unnecessary clone calls when borrowing would work
- panic! for recoverable errors instead of Result
- Over-exposing internal types with pub visibility
关键模式 — 优先确保这些内容正确:
- 使用Newtype模式避免单位混淆并编码不变量
- 函数参数优先使用借用而非所有权
- 库错误使用thiserror,应用错误使用anyhow
- 使用类型状态构建器在编译期强制检查必填字段
常见误区 — 避免这些反模式:
- 使用字符串类型API而非强类型
- 可使用借用时仍调用不必要的clone
- 对可恢复错误使用panic!而非Result
- 过度暴露内部类型的pub可见性
Table of Contents
目录
- Type Safety & Patterns — CRITICAL
- 1.1 Encode Invariants in Newtype Constructors — CRITICAL
- 1.2 Use Newtype Pattern for Unit Safety — CRITICAL
- 1.3 Replace Stringly-Typed APIs with Strong Types — CRITICAL
- 1.4 Use Non-Exhaustive for Extensible Enums — CRITICAL
- 1.5 Use PhantomData for Type-Level State — CRITICAL
- 1.6 Use Typestate Builders for Required Fields — CRITICAL
- 1.7 Use Associated Types for Related Type Relationships — HIGH
- 1.8 Use Enums for Type-Safe Variants — HIGH
- 1.9 Use Option<T> for Nullable Fields — HIGH
- 1.10 Use async_trait for Async Trait Methods — MEDIUM
- 1.11 Use bitflags! for Type-Safe Bit Flags — MEDIUM
- 1.12 Use Box<dyn Trait> for Runtime Polymorphism — MEDIUM
- 1.13 Use Builder Pattern with Method Chaining — MEDIUM
- 1.14 Derive Copy for Simple Enums — MEDIUM
- 1.15 Implement Operator Traits for Domain Types — MEDIUM
- 1.16 Use PhantomData for Unused Generic Parameters — MEDIUM
- 1.17 Use Public Fields for Data Structs — MEDIUM
- 1.18 Use Consistent Derive Order for Data Structs — MEDIUM
- 1.19 Group Related Trait Implementations Together — LOW
- 1.20 Use Type Aliases for Complex Generics — LOW
- Ownership & Borrowing — CRITICAL
- 2.1 Accept Borrowed Types Over Owned References — CRITICAL
- 2.2 Avoid Unnecessary Clone Calls — CRITICAL
- 2.3 Use Cow for Conditional Ownership — CRITICAL
- 2.4 Leverage Lifetime Elision Rules — CRITICAL
- 2.5 Prefer Borrowing Over Ownership in Function Parameters — CRITICAL
- 2.6 Return Owned Types for Caller Flexibility — CRITICAL
- Error Handling — HIGH
- 3.1 Use Two-Tier Error Strategy — HIGH
- 3.2 Use thiserror for Custom Error Types — HIGH
- 3.3 Use anyhow for Application Error Handling — HIGH
- 3.4 Use Result Instead of panic! for Recoverable Errors — HIGH
- 3.5 Reserve panic! for Unrecoverable Situations — HIGH
- 3.6 Include Path Context in IO Errors — HIGH
- 3.7 Use Option for Absence, Not Sentinel Values — HIGH
- 3.8 Use the Question Mark Operator for Error Propagation — HIGH
- 3.9 Use context() and with_context() for Error Messages — MEDIUM
- 3.10 Use bail! for Validation Failures — MEDIUM
- 3.11 Use Graceful Degradation for Non-Critical Operations — MEDIUM
- 3.12 Use #[source] for Error Chaining — MEDIUM
- 3.13 Use expect() with Descriptive Messages — LOW
- 3.14 Use ok_or_else for Expensive Error Construction — LOW
- 3.15 Define Module-Local Result Type Alias — LOW
- API Design & Traits — HIGH
- 4.1 Derive Common Traits for Public Types — HIGH
- 4.2 Implement Standard Traits for Ergonomic APIs — HIGH
- 4.3 Use Trait Bounds for Generic Flexibility — HIGH
- 4.4 Use Sealed Traits to Prevent External Implementation — HIGH
- 4.5 Use Builder Pattern for Complex Construction — HIGH
- 4.6 Use Extension Traits to Add Methods to Foreign Types — HIGH
- Project Organization — HIGH
- 5.1 Use Cargo Workspace for Multi-Crate Projects — HIGH
- 5.2 Use snake_case for All Directory Names — HIGH
- 5.3 Separate Binary and Library Crates — HIGH
- 5.4 Group Crates by Feature Domain — MEDIUM
- 5.5 Use Dedicated Common Crate for Shared Utilities — MEDIUM
- 5.6 Keep Crate Structure Flat — MEDIUM
- Module & Visibility — MEDIUM-HIGH
- 6.1 Use Explicit Module Declarations in lib.rs — HIGH
- 6.2 Co-locate Tests as test.rs Files — HIGH
- 6.3 Minimize Public API Surface — MEDIUM-HIGH
- 6.4 Use pub use for Clean Module Re-exports — MEDIUM-HIGH
- 6.5 Split Large Modules into Submodules — MEDIUM-HIGH
- 6.6 Use crate Prefix for Internal Imports — MEDIUM-HIGH
- 6.7 Use tests Submodule for Unit Tests — MEDIUM-HIGH
- 6.8 Use cfg Attributes for Conditional Modules — MEDIUM
- 6.9 Separate Types and Errors into Dedicated Files — MEDIUM
- Naming Conventions — MEDIUM-HIGH
- 7.1 Use snake_case for Functions and Methods — HIGH
- 7.2 Use PascalCase for Types — HIGH
- 7.3 Use snake_case for Module Names — HIGH
- 7.4 Use new for Constructors — HIGH
- 7.5 Use SCREAMING_SNAKE_CASE for Constants — MEDIUM
- 7.6 Prefix Getter Functions with get_ — MEDIUM
- 7.7 Use is_, has_, should_ for Boolean Predicates — MEDIUM
- 7.8 Use to_ and from_ for Conversions — MEDIUM
- 7.9 Use Descriptive Suffixes for Type Specialization — MEDIUM
- 7.10 Include Unit Suffixes in Field Names — LOW
- 7.11 Use Descriptive or Single-Letter Generic Parameters — LOW
- 7.12 Use Single Lowercase Letters for Lifetimes — LOW
- 7.13 Name Test Files as test.rs — LOW
- Conversion Traits — MEDIUM
- 8.1 Implement From Instead of Into — MEDIUM
- 8.2 Accept AsRef for Flexible String Parameters — MEDIUM
- 8.3 Implement Deref for Transparent Newtype Access — MEDIUM
- 8.4 Use TryFrom for Fallible Conversions — MEDIUM
- 8.5 Use Inner Function Pattern to Reduce Monomorphization — MEDIUM
- Idiomatic Patterns — MEDIUM
- 9.1 Implement Default Instead of new() Without Arguments — MEDIUM
- 9.2 Follow Constructor Naming Conventions — MEDIUM
- 9.3 Use let-else for Early Returns on Pattern Match Failure — MEDIUM
- 9.4 Use Struct Update Syntax for Partial Overrides — MEDIUM
- 9.5 Use Destructuring for Multiple Returns and Field Access — MEDIUM
- 9.6 Use Match Guards for Complex Conditions — MEDIUM
- Iterator & Collections — LOW-MEDIUM
- 10.1 Prefer Iterator Methods Over Manual Loops — LOW-MEDIUM
- 10.2 Use Turbofish for Explicit collect Type — LOW-MEDIUM
- 10.3 Use filter_map for Combined Filter and Transform — LOW-MEDIUM
- 10.4 Avoid Collecting Then Iterating — LOW-MEDIUM
- 10.5 Use enumerate Instead of Manual Index Tracking — LOW-MEDIUM
- 类型安全与模式 — 关键
- 1.1 在Newtype构造函数中编码不变量 — 关键
- 1.2 使用Newtype模式保证单位安全 — 关键
- 1.3 用强类型替代字符串类型API — 关键
- 1.4 对可扩展枚举使用Non-Exhaustive — 关键
- 1.5 使用PhantomData实现类型层面状态 — 关键
- 1.6 使用类型状态构建器处理必填字段 — 关键
- 1.7 使用关联类型表示相关类型关系 — 高
- 1.8 使用枚举实现类型安全的变体 — 高
- 1.9 对可空字段使用Option<T> — 高
- 1.10 对异步Trait方法使用async_trait — 中
- 1.11 使用bitflags!实现类型安全的位标志 — 中
- 1.12 使用Box<dyn Trait>实现运行时多态 — 中
- 1.13 使用链式调用的构建器模式 — 中
- 1.14 为简单枚举派生Copy — 中
- 1.15 为领域类型实现运算符Trait — 中
- 1.16 对未使用的泛型参数使用PhantomData — 中
- 1.17 为数据结构体使用公共字段 — 中
- 1.18 为数据结构体使用统一的派生顺序 — 中
- 1.19 将相关Trait实现分组存放 — 低
- 1.20 为复杂泛型使用类型别名 — 低
- 所有权与借用 — 关键
- 2.1 优先接受借用类型而非所有权引用 — 关键
- 2.2 避免不必要的clone调用 — 关键
- 2.3 使用Cow实现条件式所有权 — 关键
- 2.4 利用生命周期省略规则 — 关键
- 2.5 函数参数优先使用借用而非所有权 — 关键
- 2.6 返回所有权类型以提升调用方灵活性 — 关键
- 错误处理 — 高
- 3.1 使用双层错误处理策略 — 高
- 3.2 使用thiserror定义自定义错误类型 — 高
- 3.3 使用anyhow处理应用错误 — 高
- 3.4 对可恢复错误使用Result而非panic! — 高
- 3.5 仅对不可恢复场景使用panic! — 高
- 3.6 在IO错误中包含路径上下文 — 高
- 3.7 使用Option表示缺失值,而非哨兵值 — 高
- 3.8 使用问号运算符传播错误 — 高
- 3.9 使用context()和with_context()丰富错误信息 — 中
- 3.10 对验证失败使用bail! — 中
- 3.11 对非关键操作使用优雅降级 — 中
- 3.12 使用#[source]实现错误链 — 中
- 3.13 使用expect()并提供描述性信息 — 低
- 3.14 对开销较大的错误构造使用ok_or_else — 低
- 3.15 定义模块级别的Result类型别名 — 低
- API设计与Trait — 高
- 4.1 为公共类型派生常用Trait — 高
- 4.2 实现标准Trait以提升API易用性 — 高
- 4.3 使用Trait约束提升泛型灵活性 — 高
- 4.4 使用密封Trait防止外部实现 — 高
- 4.5 使用构建器模式处理复杂构造逻辑 — 高
- 4.6 使用扩展Trait为外部类型添加方法 — 高
- 项目组织 — 高
- 5.1 对多crate项目使用Cargo工作区 — 高
- 5.2 所有目录名称使用snake_case — 高
- 5.3 拆分二进制与库crate — 高
- 5.4 按功能领域分组crate — 中
- 5.5 使用专用公共crate存放共享工具 — 中
- 5.6 保持crate结构扁平化 — 中
- 模块与可见性 — 中-高
- 6.1 在lib.rs中使用显式模块声明 — 高
- 6.2 将测试文件与代码同目录存放为test.rs — 高
- 6.3 最小化公共API表面 — 中-高
- 6.4 使用pub use实现清晰的模块重导出 — 中-高
- 6.5 将大型模块拆分为子模块 — 中-高
- 6.6 内部导入使用crate前缀 — 中-高
- 6.7 使用tests子模块存放单元测试 — 中-高
- 6.8 使用cfg属性实现条件模块 — 中
- 6.9 将类型与错误定义拆分到专用文件 — 中
- 命名规范 — 中-高
- 7.1 函数与方法使用snake_case — 高
- 7.2 类型使用PascalCase — 高
- 7.3 模块使用snake_case — 高
- 7.4 构造函数使用new命名 — 高
- 7.5 常量使用SCREAMING_SNAKE_CASE — 中
- 7.6 getter函数添加get_前缀 — 中
- 7.7 布尔断言使用is_/has_/should_前缀 — 中
- 7.8 转换方法使用to_/from_前缀 — 中
- 7.9 为特化类型添加描述性后缀 — 中
- 7.10 字段名称包含单位后缀 — 低
- 7.11 泛型参数使用描述性名称或单字母 — 低
- 7.12 生命周期参数使用单个小写字母 — 低
- 7.13 测试文件命名为test.rs — 低
- 转换Trait — 中
- 8.1 优先实现From而非Into — 中
- 8.2 字符串参数接受AsRef以提升灵活性 — 中
- 8.3 为透明Newtype实现Deref — 中
- 8.4 对可失败转换使用TryFrom — 中
- 8.5 使用内部函数模式减少单态化 — 中
- 惯用模式 — 中
- 9.1 无参数构造函数优先实现Default而非new() — 中
- 9.2 遵循构造函数命名规范 — 中
- 9.3 使用let-else在模式匹配失败时提前返回 — 中
- 9.4 使用结构体更新语法实现部分覆盖 — 中
- 9.5 使用解构处理多返回值与字段访问 — 中
- 9.6 使用match守卫处理复杂条件 — 中
- 迭代器与集合 — 低-中
- 10.1 优先使用迭代器方法而非手动循环 — 低-中
- 10.2 使用涡轮鱼语法显式指定collect类型 — 低-中
- 10.3 使用filter_map组合过滤与转换 — 低-中
- 10.4 避免先收集再迭代 — 低-中
- 10.5 使用enumerate替代手动索引跟踪 — 低-中
References
参考资料
Related Skills
相关技能
- For performance optimization, see skill
rust-optimise
- 如需性能优化相关内容,请参考 技能
rust-optimise