Awesome-omni-skill rust-anti-pattern
Rust 反模式与常见错误。处理代码审查、clone、unwrap、String 用法、迭代器等问题。触发词:anti-pattern, common mistake, clone, unwrap, code review, 代码异味, 常见错误, 代码审查, refactor, 重构
install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/rust-anti-pattern" ~/.claude/skills/diegosouzapw-awesome-omni-skill-rust-anti-pattern-404ff0 && rm -rf "$T"
manifest:
skills/development/rust-anti-pattern/SKILL.mdsource content
Rust 反模式与常见错误
核心问题
这个模式是否掩盖了设计问题?
代码能跑不代表代码好。反模式是"能用但不该用"的模式。
Top 5 新手常犯错误
| 排名 | 错误 | 正确做法 |
|---|---|---|
| 1 | 用 躲避借用检查 | 使用引用 |
| 2 | 生产代码用 | 用 或 |
| 3 | 什么都是 | 用 ,必要时用 |
| 4 | 索引循环 | 用迭代器 , |
| 5 | 与生命周期对抗 | 重新设计数据结构 |
常见反模式
反模式 1:到处 clone
// ❌ 不好:躲避借用检查 fn process(user: User) { let name = user.name.clone(); // 为什么需要 clone? // ... } // ✅ 好:直接使用引用 fn process(user: &User) { let name = &user.name; // 借用即可 }
什么时候真的需要 clone:
- 确实需要独立副本
- API 设计需要 owned 值
- 数据流向需要
反模式 2:生产代码用 unwrap
// ❌ 不好:可能 panic let config = File::open("config.json").unwrap(); // ✅ 好:传播错误 let config = File::open("config.json")?; // ✅ 好:带上下文 let config = File::open("config.json") .context("failed to open config")?;
反模式 3:String everywhere
// ❌ 不好:不必要的分配 fn greet(name: String) { println!("Hello, {}", name); } // ✅ 好:借用即可 fn greet(name: &str) { println!("Hello, {}", name); } // 确实需要 String 的场景:需要持有或修改
反模式 4:索引循环
// ❌ 不好:容易出错,效率低 for i in 0..items.len() { println!("{}: {}", i, items[i]); } // ✅ 好:直接迭代 for item in &items { println!("{}", item); } // ✅ 好:需要索引 for (i, item) in items.iter().enumerate() { println!("{}: {}", i, item); }
反模式 5:过度 unsafe
// ❌ 不好:为了省事用 unsafe unsafe { let ptr = data.as_mut_ptr(); // ... 复杂的内存操作 } // ✅ 好:寻找安全的抽象 let mut data: Vec<u8> = vec![0; size]; // Vec 已经处理了内存管理
代码异味速查
| 现象 | 暗示问题 | 重构方向 |
|---|---|---|
很多 | 所有权不清晰 | 明确数据流 |
很多 | 错误处理缺失 | 添加 Result 处理 |
很多 字段 | 封装被破坏 | 私有 + 访问器 |
| 深度嵌套 | 逻辑复杂 | 提取方法 |
| 函数过长 (>50行) | 职责过多 | 拆分职责 |
| 巨大的枚举 | 缺少抽象 | Trait + 类型 |
过时写法 → 现代写法
| 过时 | 现代 |
|---|---|
索引循环 | |
然后再遍历 | 链式迭代器 |
| |
转换 | 或 |
| 自定义链表 | 或 |
| 手动 unsafe cell | , |
代码审查清单
- 没有无理由的
.clone() - 库代码没有
.unwrap() - 没有带不变式的
字段pub - 迭代器可用时不使用索引循环
-
够用时不使用&strString - 没有忽略
警告#[must_use] -
有 SAFETY 注释unsafe - 没有巨型函数 (>50 行)
问自己这些问题
-
这段代码在对抗 Rust 还是在配合 Rust?
- 对抗 → 重新设计
- 配合 → 继续
-
这个 clone 是必要的吗?
- 为了躲避借用 → 错误信号
- 确实需要 → 保留
-
这个 unwrap 会导致 panic 吗?
- 可能 → 用
? - 绝不会 →
expect("reason")
- 可能 → 用
-
有更 idiomatic 的方式吗?
- 参考其他 Rust 代码
- 查阅 std 库 API