名称: rust-refactor 描述: Rust 应用程序的架构重构指南,涵盖类型安全、所有权模式、错误处理策略、API 设计、项目组织、模块结构、命名约定、转换特性和习惯用法。适用于重构 Rust 代码库、审查 PR 中的架构问题、提高类型安全、设计错误处理策略或组织项目结构。补充 rust-optimise 技能(性能模式)。不涵盖性能优化、内存分配或异步并发调优(参见 rust-optimise 技能)。
Rust 重构最佳实践
Rust 应用程序的架构重构指南。包含 10 个类别的 91 条规则,按影响优先级从关键(类型安全、所有权)到增量(迭代器习惯用法)排序。
何时应用
- 重构现有 Rust 代码库或规划大规模重构
- 审查 PR 中的架构问题和代码异味
- 设计具有适当错误处理的类型安全 API
- 使用 Cargo 工作区组织 Rust 项目结构
- 改进模块边界和可见性控制
- 应用一致的命名约定(RFC 430)
- 用强类型替换字符串类型 API
规则类别
| 类别 | 影响 | 规则数 | 关键主题 |
|---|---|---|---|
| 类型安全与模式 | 关键 | 20 | 新类型、类型状态构建器、PhantomData、枚举、特质对象、关联类型 |
| 所有权与借用 | 关键 | 6 | 借用、Cow、生命周期省略、避免克隆 |
| 错误处理 | 高 | 15 | thiserror/anyhow、两层策略、上下文、优雅降级 |
| API 设计与特质 | 高 | 6 | 密封特质、扩展特质、泛型约束、构建器模式 |
| 项目组织 | 高 | 6 | Cargo 工作区、crate 分离、功能分组 |
| 模块与可见性 | 中高 | 9 | 重新导出、可见性控制、测试同位置、模块拆分 |
| 命名约定 | 中高 | 13 | RFC 430、snake_case、PascalCase、谓词、单位后缀 |
| 转换特性 | 中 | 5 | From/Into、AsRef、TryFrom、Deref |
| 习惯用法 | 中 | 6 | Default、let-else、解构、匹配守卫 |
| 迭代器与集合 | 低中 | 5 | 迭代器方法、collect turbofish、filter_map |
快速参考
关键模式 — 优先关注这些:
- 使用新类型模式防止单位混淆和编码不变性
- 在函数参数中优先借用而非所有权
- 库错误使用 thiserror,应用程序错误使用 anyhow
- 使用类型状态构建器进行编译时必需字段强制执行
常见错误 — 避免这些反模式:
- 使用字符串类型 API 而非强类型
- 可用借用时进行不必要的克隆调用
- 可恢复错误使用 panic! 而非 Result
- 过度暴露内部类型使用 pub 可见性
目录
- 类型安全与模式 — 关键
- 1.1 在新类型构造函数中编码不变性 — 关键
- 1.2 使用新类型模式确保单位安全 — 关键
- 1.3 用强类型替换字符串类型 API — 关键
- 1.4 为可扩展枚举使用 Non-Exhaustive — 关键
- 1.5 使用 PhantomData 进行类型级别状态管理 — 关键
- 1.6 使用类型状态构建器强制执行必需字段 — 关键
- 1.7 使用关联类型处理相关类型关系 — 高
- 1.8 使用枚举实现类型安全变体 — 高
- 1.9 使用 Option<T> 处理可空字段 — 高
- 1.10 使用 async_trait 处理异步特质方法 — 中
- 1.11 使用 bitflags! 实现类型安全位标志 — 中
- 1.12 使用 Box<dyn Trait> 进行运行时多态 — 中
- 1.13 使用链式方法构建器模式 — 中
- 1.14 为简单枚举派生 Copy — 中
- 1.15 为领域类型实现运算符特质 — 中
- 1.16 为未使用泛型参数使用 PhantomData — 中
- 1.17 为数据结构使用公共字段 — 中
- 1.18 为数据结构使用一致的派生顺序 — 中
- 1.19 将相关特质实现分组 — 低
- 1.20 使用类型别名简化复杂泛型 — 低
- 所有权与借用 — 关键
- 2.1 接受借用类型而非拥有引用 — 关键
- 2.2 避免不必要的克隆调用 — 关键
- 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 设计与特质 — 高
- 4.1 为公共类型派生常用特质 — 高
- 4.2 为标准特质实现以实现符合人体工程学的 API — 高
- 4.3 使用特质边界实现泛型灵活性 — 高
- 4.4 使用密封特质防止外部实现 — 高
- 4.5 使用构建器模式处理复杂构造 — 高
- 4.6 使用扩展特质为外部类型添加方法 — 高
- 项目组织 — 高
- 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 获取函数前缀 get_ — 中
- 7.7 布尔谓词使用 is_、has_、should_ — 中
- 7.8 转换使用 to_ 和 from_ — 中
- 7.9 使用描述性后缀进行类型特化 — 中
- 7.10 字段名称包含单位后缀 — 低
- 7.11 使用描述性或单字母泛型参数 — 低
- 7.12 生命周期参数使用单小写字母 — 低
- 7.13 测试文件命名为 test.rs — 低
- 转换特性 — 中
- 8.1 实现 From 而非 Into — 中
- 8.2 接受 AsRef 以提供灵活字符串参数 — 中
- 8.3 为透明新类型访问实现 Deref — 中
- 8.4 使用 TryFrom 进行可能失败的转换 — 中
- 8.5 使用内部函数模式减少单态化 — 中
- 习惯用法 — 中
- 9.1 实现 Default 而非无参数 new() — 中
- 9.2 遵循构造函数命名约定 — 中
- 9.3 使用 let-else 处理模式匹配失败的早期返回 — 中
- 9.4 使用结构更新语法进行部分覆盖 — 中
- 9.5 使用解构处理多重返回和字段访问 — 中
- 9.6 使用匹配守卫处理复杂条件 — 中
- 迭代器与集合 — 低中
- 10.1 优先使用迭代器方法而非手动循环 — 低中
- 10.2 使用 turbofish 指定明确的 collect 类型 — 低中
- 10.3 使用 filter_map 进行过滤和转换组合 — 低中
- 10.4 避免收集后迭代 — 低中
- 10.5 使用 enumerate 而非手动索引跟踪 — 低中
参考文献
- https://rust-lang.github.io/api-guidelines/
- https://rust-unofficial.github.io/patterns/
- https://doc.rust-lang.org/book/
- https://www.lurklurk.org/effective-rust/
- https://rust-lang.github.io/rust-clippy/
相关技能
- 有关性能优化,请参见
rust-optimise技能