用途
本技能用于在代码审查中识别所谓「反模式」(anti-pattern)。它是一个面向 Rust 的设计层技能(Layer 2: Design Choices),核心问题是:某个模式是否在掩盖更深层的设计问题?适用于当你看到可疑代码、需要判断某段实现是否为反模式、或想寻找更符合 Rust 习惯的替代写法时。
关键词包括:anti-pattern、common mistake、pitfall、code smell、bad practice、code review、is this an anti-pattern 等。
审查时的思考方向
该技能建议在审查代码时追问几个问题:这个写法是在解决症状还是根因?有没有更符合习惯(idiomatic)的做法?这个写法是在对抗 Rust 还是顺应 Rust?
反模式与更优模式对照
技能提供了一张对照表,帮助快速定位问题与改进方向:
- 到处
.clone():掩盖所有权问题;应使用合适的引用或所有权。 - 生产代码中的
.unwrap():会导致运行时 panic;应使用?、expect或正确处理。 - 单一所有者时使用
Rc:带来不必要的开销;应使用简单所有权。 - 为方便而使用
unsafe:存在未定义行为(UB)风险;应寻找安全模式。 - 通过
Deref模拟 OOP:API 具有误导性;应使用组合与 trait。 - 巨型 match 分支:难以维护;应抽取为方法。
- 到处使用
String:造成不必要的内存分配;应使用&str、Cow<str>。 - 忽略
#[must_use]:丢失错误;应处理或使用let _ =。
何时可见为反模式的思考提示
当看到可疑代码时,技能建议判断它是症状还是根因,例如:为了规避借用检查而 clone,通常是所有权设计问题;以「它不会失败」为由 unwrap,通常是未处理的错误分支。同时思考符合习惯的写法应是什么样:用引用代替克隆、用迭代器代替索引循环、用模式匹配代替标志位。还要判断代码是否在对抗 Rust:如果一直在和借用检查器斗争,应重构结构;如果 unsafe 过多,应寻找安全模式。
向上/向下追溯
技能提供追溯路径,帮助定位问题根源与实现方案:
向上追溯(到设计理解):例如「为什么我的代码有这么多 clone?」可进一步追问所有权模型是否正确,检查 m09-domain(数据流设计)与 m01-ownership(引用模式)。反模式可追溯到对应技能:clone 到处出现 → m01-ownership(谁应拥有这份数据?);unwrap 到处出现 → m06-error-handling(错误策略是什么?);Rc 到处出现 → m09-domain(所有权是否清晰?);与生命周期搏斗 → m09-domain(数据结构是否应改变?)。
向下追溯(到实现层):例如「用合适的所有权替换 clone」可落到 m01-ownership(引用模式)与 m02-resource(必要时使用智能指针);「用正确处理替换 unwrap」可落到 m06-error-handling(? 运算符、带消息的 expect)。
初学者五大常见错误
表中列出排名前五的初学者错误及修复方式:
- 为逃避借用检查而 clone → 使用引用。
- 生产环境使用 unwrap → 用
?传播错误。 - 所有东西都用 String → 使用 &str。
- 索引循环 → 使用迭代器。
- 与生命周期搏斗 → 重构为拥有数据。
代码异味与重构
技能还给出一组代码异味对应的重构方向:大量 .clone() 表示所有权不清晰 → 理清数据流;大量 .unwrap() 表示缺少错误处理 → 加入正确处理;大量 pub 字段表示封装被破坏 → 私有化 + 访问器;深层嵌套表示逻辑复杂 → 抽取方法;超长函数表示职责过多 → 拆分;巨型枚举表示缺少抽象 → trait + 类型。
常见错误模式
针对常见错误给出反模式成因与修复:E0382 use after move(克隆 vs 所有权 → 合适的引用);生产环境 panic(到处 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。
限制
以上内容均来自技能文档本身,未提供具体安装命令、版本或运行方式等额外信息。