rust-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseRust Best Practices
Rust最佳实践
Apply these guidelines when writing or reviewing Rust code. Based on Apollo GraphQL's Rust Best Practices Handbook.
编写或评审Rust代码时请遵循以下指南。本指南基于Apollo GraphQL的Rust最佳实践手册。
Best Practices Reference
最佳实践参考
Before reviewing, familiarize yourself with Apollo's Rust best practices. Read ALL relevant chapters in the same turn in parallel. Reference these files when providing feedback:
- Chapter 1 - Coding Styles and Idioms: Borrowing vs cloning, Copy trait, Option/Result handling, iterators, comments
- Chapter 2 - Clippy and Linting: Clippy configuration, important lints, workspace lint setup
- Chapter 3 - Performance Mindset: Profiling, avoiding redundant clones, stack vs heap, zero-cost abstractions
- Chapter 4 - Error Handling: Result vs panic, thiserror vs anyhow, error hierarchies
- Chapter 5 - Automated Testing: Test naming, one assertion per test, snapshot testing
- Chapter 6 - Generics and Dispatch: Static vs dynamic dispatch, trait objects
- Chapter 7 - Type State Pattern: Compile-time state safety, when to use it
- Chapter 8 - Comments vs Documentation: When to comment, doc comments, rustdoc
- Chapter 9 - Understanding Pointers: Thread safety, Send/Sync, pointer types
评审前,请先熟悉Apollo的Rust最佳实践。同时阅读所有相关章节。提供反馈时请参考以下文件:
- 第1章 - 编码风格与惯用写法:借用与克隆、Copy trait、Option/Result处理、迭代器、注释
- 第2章 - Clippy与代码检查:Clippy配置、重要检查项、工作区检查设置
- 第3章 - 性能思维:性能分析、避免冗余克隆、栈与堆、零成本抽象
- 第4章 - 错误处理:Result与panic、thiserror与anyhow、错误层级
- 第5章 - 自动化测试:测试命名、单测试单断言、快照测试
- 第6章 - 泛型与分发:静态分发与动态分发、 trait对象
- 第7章 - 类型状态模式:编译时状态安全、适用场景
- 第8章 - 注释与文档:注释的使用时机、文档注释、rustdoc
- 第9章 - 指针理解:线程安全、Send/Sync、指针类型
Quick Reference
快速参考
Borrowing & Ownership
借用与所有权
- Prefer over
&Tunless ownership transfer is required.clone() - Use over
&str,Stringover&[T]in function parametersVec<T> - Small types (≤24 bytes) can be passed by value
Copy - Use when ownership is ambiguous
Cow<'_, T>
- 除非需要转移所有权,否则优先使用而非
&T.clone() - 函数参数中优先使用而非
&str,String而非&[T]Vec<T> - 小型类型(≤24字节)可按值传递
Copy - 当所有权不明确时,使用
Cow<'_, T>
Error Handling
错误处理
- Return for fallible operations; avoid
Result<T, E>in productionpanic! - Never use /
unwrap()outside testsexpect() - Use for library errors,
thiserrorfor binaries onlyanyhow - Prefer operator over match chains for error propagation
?
- 针对可能失败的操作返回;生产环境中避免使用
Result<T, E>panic! - 测试场景外禁止使用/
unwrap()expect() - 库错误处理使用,仅在二进制程序中使用
thiserroranyhow - 错误传播优先使用运算符而非match链式调用
?
Performance
性能优化
- Always benchmark with flag
--release - Run for performance hints
cargo clippy -- -D clippy::perf - Avoid cloning in loops; use instead of
.iter()for Copy types.into_iter() - Prefer iterators over manual loops; avoid intermediate calls
.collect()
- 始终使用标志进行基准测试
--release - 运行获取性能提示
cargo clippy -- -D clippy::perf - 避免在循环中克隆;对于Copy类型,使用而非
.iter().into_iter() - 优先使用迭代器而非手动循环;避免中间的调用
.collect()
Linting
代码检查
Run regularly:
cargo clippy --all-targets --all-features --locked -- -D warningsKey lints to watch:
- - unnecessary cloning
redundant_clone - - oversized variants (consider boxing)
large_enum_variant - - premature collection
needless_collect
Use over with justification comment.
#[expect(clippy::lint)]#[allow(...)]定期运行:
cargo clippy --all-targets --all-features --locked -- -D warnings重点关注的检查项:
- - 不必要的克隆
redundant_clone - - 过大的枚举变体(考虑装箱)
large_enum_variant - - 过早的集合操作
needless_collect
优先使用而非,并附上理由注释。
#[expect(clippy::lint)]#[allow(...)]Testing
测试
- Name tests descriptively:
process_should_return_error_when_input_empty() - One assertion per test when possible
- Use doc tests () for public API examples
/// - Consider for snapshot testing generated output
cargo insta
- 测试命名要具有描述性:例如
process_should_return_error_when_input_empty() - 尽可能每个测试仅包含一个断言
- 公共API示例使用文档测试()
/// - 生成的输出可考虑使用进行快照测试
cargo insta
Generics & Dispatch
泛型与分发
- Prefer generics (static dispatch) for performance-critical code
- Use only when heterogeneous collections are needed
dyn Trait - Box at API boundaries, not internally
- 性能关键型代码优先使用泛型(静态分发)
- 仅当需要异构集合时使用
dyn Trait - 在API边界处进行装箱,而非内部
Type State Pattern
类型状态模式
Encode valid states in the type system to catch invalid operations at compile time:
rust
struct Connection<State> { /* ... */ _state: PhantomData<State> }
struct Disconnected;
struct Connected;
impl Connection<Connected> {
fn send(&self, data: &[u8]) { /* only connected can send */ }
}在类型系统中编码有效状态,以便在编译时捕获无效操作:
rust
struct Connection<State> { /* ... */ _state: PhantomData<State> }
struct Disconnected;
struct Connected;
impl Connection<Connected> {
fn send(&self, data: &[u8]) { /* only connected can send */ }
}Documentation
文档
- comments explain why (safety, workarounds, design rationale)
// - doc comments explain what and how for public APIs
/// - Every needs a linked issue:
TODO// TODO(#42): ... - Enable for libraries
#![deny(missing_docs)]
- 注释用于解释原因(安全考量、变通方案、设计依据)
// - 文档注释用于解释公共API的功能和使用方式
/// - 所有都需要关联议题:
TODO// TODO(#42): ... - 库中启用检查
#![deny(missing_docs)]