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.md
source content

Rust 反模式与常见错误

核心问题

这个模式是否掩盖了设计问题?

代码能跑不代表代码好。反模式是"能用但不该用"的模式。


Top 5 新手常犯错误

排名错误正确做法
1
.clone()
躲避借用检查
使用引用
2生产代码用
.unwrap()
?
with_context()
3什么都是
String
&str
,必要时用
Cow<str>
4索引循环用迭代器
.iter()
,
.enumerate()
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 已经处理了内存管理

代码异味速查

现象暗示问题重构方向
很多
.clone()
所有权不清晰明确数据流
很多
.unwrap()
错误处理缺失添加 Result 处理
很多
pub
字段
封装被破坏私有 + 访问器
深度嵌套逻辑复杂提取方法
函数过长 (>50行)职责过多拆分职责
巨大的枚举缺少抽象Trait + 类型

过时写法 → 现代写法

过时现代
索引循环
.items[i]
.iter().enumerate()
collect::<Vec<_>>()
然后再遍历
链式迭代器
lazy_static!
std::sync::OnceLock
mem::transmute
转换
as
TryFrom
自定义链表
Vec
VecDeque
手动 unsafe cell
Cell
,
RefCell

代码审查清单

  • 没有无理由的
    .clone()
  • 库代码没有
    .unwrap()
  • 没有带不变式的
    pub
    字段
  • 迭代器可用时不使用索引循环
  • &str
    够用时不使用
    String
  • 没有忽略
    #[must_use]
    警告
  • unsafe
    有 SAFETY 注释
  • 没有巨型函数 (>50 行)

问自己这些问题

  1. 这段代码在对抗 Rust 还是在配合 Rust?

    • 对抗 → 重新设计
    • 配合 → 继续
  2. 这个 clone 是必要的吗?

    • 为了躲避借用 → 错误信号
    • 确实需要 → 保留
  3. 这个 unwrap 会导致 panic 吗?

    • 可能 → 用
      ?
    • 绝不会 →
      expect("reason")
  4. 有更 idiomatic 的方式吗?

    • 参考其他 Rust 代码
    • 查阅 std 库 API