SKILL.md
readonlyread-only
name
m15-anti-pattern
description
用於審查程式碼中的反模式。關鍵字:反模式、常見錯誤、陷阱、程式碼異味、不良實踐、程式碼審查、這是不是反模式、更好的做法、要避免的常見錯誤、為什麼這樣不好、慣用寫法、初學者錯誤、與借用檢查器搏鬥、到處 clone、在生產環境中使用 unwrap、我應該重構嗎、反模式、常见错误、代码异味、最佳实践、地道写法
反模式
第 2 層:設計選擇
核心問題
這個模式是否隱藏了設計問題?
審查程式碼時:
- 這是在解決症狀還是原因?
- 有沒有更慣用的做法?
- 這是與 Rust 對抗還是順應?
反模式 → 更好的模式
| 反模式 | 為什麼不好 | 更好的做法 |
|---|---|---|
到處 .clone() |
隱藏所有權問題 | 適當的引用或所有權 |
在生產環境中使用 .unwrap() |
執行時期恐慌 | ?、expect 或處理 |
單一擁有者使用 Rc |
不必要的開銷 | 簡單的所有權 |
為了方便使用 unsafe |
未定義行為風險 | 尋找安全模式 |
透過 Deref 實現 OOP |
誤導的 API | 組合、特徵 |
| 巨大的 match 分支 | 難以維護 | 提取成方法 |
到處使用 String |
浪費分配 | &str、Cow<str> |
忽略 #[must_use] |
遺失錯誤 | 處理或 let _ = |
思考提示
看到可疑程式碼時:
-
這是症狀還是原因?
- 為了避免借用而 clone?→ 所有權設計問題
- 因為「不會失敗」而 unwrap?→ 未處理的情況
-
慣用的程式碼會長怎樣?
- 使用引用而非 clone
- 使用迭代器而非索引迴圈
- 使用模式匹配而非旗標
-
這是在對抗 Rust 嗎?
- 與借用檢查器搏鬥 → 重構
- 過多的 unsafe → 尋找安全模式
向上追溯 ↑
到設計理解:
「為什麼我的程式碼有這麼多 clone?」
↑ 問:所有權模型是否正確?
↑ 查看:m09-domain(資料流程設計)
↑ 查看:m01-ownership(引用模式)
| 反模式 | 追溯至 | 問題 |
|---|---|---|
| 到處 clone | m01-ownership | 誰應該擁有這筆資料? |
| 到處 unwrap | m06-error-handling | 錯誤策略是什麼? |
| 到處 Rc | m09-domain | 所有權是否清楚? |
| 與生命週期搏鬥 | m09-domain | 資料結構是否該改變? |
向下追溯 ↓
到實作(第 1 層):
「用適當的所有權取代 clone」
↓ m01-ownership:引用模式
↓ m02-resource:必要時使用智慧指標
「用適當的處理取代 unwrap」
↓ m06-error-handling:? 運算子
↓ m06-error-handling:附帶訊息的 expect
前 5 大初學者錯誤
| 排名 | 錯誤 | 修正 |
|---|---|---|
| 1 | 用 clone 逃離借用檢查器 | 使用引用 |
| 2 | 在生產環境中使用 unwrap | 用 ? 傳播 |
| 3 | 所有文字都用 String | 使用 &str |
| 4 | 索引迴圈 | 使用迭代器 |
| 5 | 與生命週期搏鬥 | 重構以擁有資料 |
程式碼異味 → 重構
| 異味 | 表示 | 重構 |
|---|---|---|
很多 .clone() |
所有權不明確 | 釐清資料流程 |
很多 .unwrap() |
缺少錯誤處理 | 加入適當處理 |
很多 pub 欄位 |
封裝被破壞 | 私有 + 存取子 |
| 深層巢狀 | 複雜邏輯 | 提取方法 |
| 長函式 | 多重責任 | 拆分 |
| 巨大列舉 | 缺少抽象 | 特徵 + 型別 |
常見錯誤模式
| 錯誤 | 反模式原因 | 修正 |
|---|---|---|
| E0382 使用後移動 | clone 與所有權 | 適當的引用 |
| 生產環境恐慌 | 到處 unwrap | ?、匹配 |
| 效能緩慢 | 所有文字都用 String | &str、Cow |
| 與借用檢查器搏鬥 | 錯誤的結構 | 重構 |
| 記憶體膨脹 | 到處 Rc/Arc | 簡單的所有權 |
已棄用 → 更好的做法
| 已棄用 | 更好的做法 |
|---|---|
| 基於索引的迴圈 | .iter()、.enumerate() |
先 collect::<Vec<_>>() 再迭代 |
鏈式迭代器 |
| 手動 unsafe cell | Cell、RefCell |
用 mem::transmute 做型別轉換 |
as 或 TryFrom |
| 自訂鏈結串列 | Vec、VecDeque |
lazy_static! |
std::sync::OnceLock |
快速審查檢查清單
- [ ] 沒有未經正當理由的
.clone() - [ ] 函式庫程式碼中沒有
.unwrap() - [ ] 沒有帶不變量的
pub欄位 - [ ] 沒有可用迭代器卻用索引迴圈的情況
- [ ] 沒有
&str就夠卻用String的情況 - [ ] 沒有忽略
#[must_use]警告 - [ ] 沒有缺少 SAFETY 註解的
unsafe - [ ] 沒有巨大函式(超過 50 行)
相關技能
| 時機 | 查看 |
|---|---|
| 所有權模式 | m01-ownership |
| 錯誤處理 | m06-error-handling |
| 心智模型 | m14-mental-model |
| 效能 | m10-performance |






