m15-anti-pattern by zhanghandong/rust-skills
npx skills add https://github.com/zhanghandong/rust-skills --skill m15-anti-pattern第二层:设计选择
这个模式是否掩盖了设计问题?
审查代码时:
| 反模式 | 为何不好 | 更好的方式 |
|---|---|---|
到处使用 .clone() | 掩盖所有权问题 | 正确的引用或所有权 |
生产环境中使用 .unwrap() | 导致运行时恐慌 | ?、expect 或错误处理 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
单一所有者时使用 Rc | 不必要的开销 | 简单的所有权 |
为方便而使用 unsafe | 未定义行为风险 | 寻找安全模式 |
通过 Deref 实现 OOP | 误导性的 API | 组合、特征 |
| 庞大的 match 分支 | 难以维护 | 提取为方法 |
到处使用 String | 分配浪费 | &str、Cow<str> |
忽略 #[must_use] | 丢失错误 | 处理或使用 let _ = |
看到可疑代码时:
这是症状还是根源?
符合语言习惯的代码应该是什么样子?
这是在与 Rust 对抗吗?
通向设计理解:
"为什么我的代码有这么多克隆?"
↑ 提问:所有权模型正确吗?
↑ 检查:m09-domain (数据流设计)
↑ 检查:m01-ownership (引用模式)
| 反模式 | 追溯至 | 问题 |
|---|---|---|
| 到处克隆 | m01-ownership | 谁应该拥有这些数据? |
| 到处 unwrap | m06-error-handling | 错误处理策略是什么? |
| 到处使用 Rc | m09-domain | 所有权清晰吗? |
| 与生命周期斗争 | m09-domain | 数据结构应该改变吗? |
通向实现(第一层):
"用正确的所有权替换克隆"
↓ m01-ownership: 引用模式
↓ m02-resource: 必要时使用智能指针
"用正确的处理替换 unwrap"
↓ m06-error-handling: ? 运算符
↓ m06-error-handling: 带消息的 expect
| 排名 | 错误 | 修复方法 |
|---|---|---|
| 1 | 通过克隆逃避借用检查器 | 使用引用 |
| 2 | 生产环境中使用 unwrap | 使用 ? 传播错误 |
| 3 | 所有地方都用 String | 使用 &str |
| 4 | 索引循环 | 使用迭代器 |
| 5 | 与生命周期斗争 | 重构以拥有数据 |
| 异味 | 表明 | 重构方法 |
|---|---|---|
大量 .clone() | 所有权不清晰 | 明确数据流 |
大量 .unwrap() | 缺少错误处理 | 添加正确的处理 |
大量 pub 字段 | 封装被破坏 | 私有化 + 访问器 |
| 深层嵌套 | 逻辑复杂 | 提取方法 |
| 函数过长 | 承担多重职责 | 拆分 |
| 庞大的枚举 | 缺少抽象 | 特征 + 类型 |
| 错误 | 反模式原因 | 修复方法 |
|---|---|---|
| E0382 移动后使用 | 克隆 vs 所有权 | 正确的引用 |
| 生产环境恐慌 | 到处使用 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] 警告unsafe| 时机 | 参见 |
|---|---|
| 所有权模式 | m01-ownership |
| 错误处理 | m06-error-handling |
| 心智模型 | m14-mental-model |
| 性能 | m10-performance |
每周安装量
3.1K
仓库
GitHub 星标数
912
首次出现
2026年1月20日
安全审计
安装于
claude-code2.5K
opencode1.6K
codex1.6K
gemini-cli1.5K
github-copilot1.5K
amp1.5K
Layer 2: Design Choices
Is this pattern hiding a design problem?
When reviewing code:
| Anti-Pattern | Why Bad | Better |
|---|---|---|
.clone() everywhere | Hides ownership issues | Proper references or ownership |
.unwrap() in production | Runtime panics | ?, expect, or handling |
Rc when single owner | Unnecessary overhead | Simple ownership |
unsafe for convenience | UB risk | Find safe pattern |
OOP via Deref | Misleading API | Composition, traits |
| Giant match arms | Unmaintainable | Extract to methods |
String everywhere | Allocation waste | &str, Cow<str> |
Ignoring #[must_use] | Lost errors | Handle or let _ = |
When seeing suspicious code:
Is this symptom or cause?
What would idiomatic code look like?
Does this fight Rust?
To design understanding:
"Why does my code have so many clones?"
↑ Ask: Is the ownership model correct?
↑ Check: m09-domain (data flow design)
↑ Check: m01-ownership (reference patterns)
| Anti-Pattern | Trace To | Question |
|---|---|---|
| Clone everywhere | m01-ownership | Who should own this data? |
| Unwrap everywhere | m06-error-handling | What's the error strategy? |
| Rc everywhere | m09-domain | Is ownership clear? |
| Fighting lifetimes | m09-domain | Should data structure change? |
To implementation (Layer 1):
"Replace clone with proper ownership"
↓ m01-ownership: Reference patterns
↓ m02-resource: Smart pointer if needed
"Replace unwrap with proper handling"
↓ m06-error-handling: ? operator
↓ m06-error-handling: expect with message
| Rank | Mistake | Fix |
|---|---|---|
| 1 | Clone to escape borrow checker | Use references |
| 2 | Unwrap in production | Propagate with ? |
| 3 | String for everything | Use &str |
| 4 | Index loops | Use iterators |
| 5 | Fighting lifetimes | Restructure to own data |
| Smell | Indicates | Refactoring |
|---|---|---|
Many .clone() | Ownership unclear | Clarify data flow |
Many .unwrap() | Error handling missing | Add proper handling |
Many pub fields | Encapsulation broken | Private + accessors |
| Deep nesting | Complex logic | Extract methods |
| Long functions | Multiple responsibilities | Split |
| Giant enums | Missing abstraction | Trait + types |
| Error | Anti-Pattern Cause | Fix |
|---|---|---|
| E0382 use after move | Cloning vs ownership | Proper references |
| Panic in production | Unwrap everywhere | ?, matching |
| Slow performance | String for all text | &str, Cow |
| Borrow checker fights | Wrong structure | Restructure |
| Memory bloat | Rc/Arc everywhere | Simple ownership |
| Deprecated | Better |
|---|---|
| Index-based loops | .iter(), .enumerate() |
collect::<Vec<_>>() then iterate | Chain iterators |
| Manual unsafe cell | Cell, RefCell |
mem::transmute for casts | as or TryFrom |
.clone() without justification.unwrap() in library codepub fields with invariantsString where &str suffices#[must_use] warningsunsafe without SAFETY comment| When | See |
|---|---|
| Ownership patterns | m01-ownership |
| Error handling | m06-error-handling |
| Mental models | m14-mental-model |
| Performance | m10-performance |
Weekly Installs
3.1K
Repository
GitHub Stars
912
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code2.5K
opencode1.6K
codex1.6K
gemini-cli1.5K
github-copilot1.5K
amp1.5K
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
102,200 周安装
| Custom linked list | Vec, VecDeque |
lazy_static! | std::sync::OnceLock |