SKILL.md
readonlyread-only
name
rust-best-practices
description
Guide for writing idiomatic Rust code based on Apollo GraphQL's best practices handbook. Use this skill when: (1) writing new Rust code or functions, (2) reviewing or refactoring existing Rust code, (3) deciding between borrowing vs cloning or ownership patterns, (4) implementing error handling with Result types, (5) optimizing Rust code for performance, (6) writing tests or documentation for Rust projects.
Rust 最佳實務
撰寫或審查 Rust 程式碼時,請遵循以下準則。本指南基於 Apollo GraphQL 的 Rust 最佳實務手冊。
最佳實務參考
在審查之前,請先熟悉 Apollo 的 Rust 最佳實務。請在同一輪中平行閱讀所有相關章節。提供意見回饋時,請參考以下檔案:
- 第一章 - 程式碼風格與慣用寫法:借用 vs 複製、Copy trait、Option/Result 處理、迭代器、註解
- 第二章 - Clippy 與 Linting:Clippy 設定、重要 lint、工作區 lint 設定
- 第三章 - 效能思維:效能剖析、避免重複複製、堆疊 vs 堆積、零成本抽象
- 第四章 - 錯誤處理:Result vs panic、thiserror vs anyhow、錯誤層級
- 第五章 - 自動化測試:測試命名、每個測試一個斷言、快照測試
- 第六章 - 泛型與分派:靜態 vs 動態分派、trait 物件
- 第七章 - 型別狀態模式:編譯時期狀態安全、使用時機
- 第八章 - 註解 vs 文件:何時加註解、doc 註解、rustdoc
- 第九章 - 理解指標:執行緒安全、Send/Sync、指標型別
快速參考
借用與所有權
- 除非需要轉移所有權,否則優先使用
&T而非.clone() - 函式參數優先使用
&str而非String、&[T]而非Vec<T> - 小型
Copy型別(≤24 位元組)可以傳值 - 當所有權不明確時,使用
Cow<'_, T>
錯誤處理
- 可能失敗的操作回傳
Result<T, E>;避免在正式環境中使用panic! - 絕不在測試以外的程式碼中使用
unwrap()/expect() - 函式庫錯誤使用
thiserror,僅二進位檔使用anyhow - 錯誤傳播優先使用
?運算子而非 match 鏈
效能
- 務必使用
--release旗標進行基準測試 - 執行
cargo clippy -- -D clippy::perf取得效能提示 - 避免在迴圈中複製;對
Copy型別使用.iter()而非.into_iter() - 優先使用迭代器而非手動迴圈;避免中間的
.collect()呼叫
Linting
定期執行:cargo clippy --all-targets --all-features --locked -- -D warnings
需注意的重要 lint:
redundant_clone- 不必要的複製large_enum_variant- 過大的變體(考慮使用 Box)needless_collect- 過早的集合轉換
使用 #[expect(clippy::lint)] 而非 #[allow(...)],並附上理由註解。
測試
- 測試命名要具描述性:
process_should_return_error_when_input_empty() - 盡可能每個測試只有一個斷言
- 公開 API 範例使用 doc 測試(
///) - 考慮使用
cargo insta對產生的輸出進行快照測試
泛型與分派
- 效能關鍵的程式碼優先使用泛型(靜態分派)
- 僅在需要異質集合時使用
dyn Trait - 在 API 邊界使用 Box,而非內部
型別狀態模式
將有效狀態編碼在型別系統中,以便在編譯時期捕捉無效操作:
struct Connection<State> { /* ... */ _state: PhantomData<State> }
struct Disconnected;
struct Connected;
impl Connection<Connected> {
fn send(&self, data: &[u8]) { /* 只有已連線才能傳送 */ }
}
文件
//註解說明 為什麼(安全性、變通方法、設計理由)///doc 註解說明公開 API 的 什麼 與 如何- 每個
TODO都需要連結到一個 issue:// TODO(#42): ... - 函式庫啟用
#![deny(missing_docs)]






