| name | rust-anti-pattern |
| description | Rust anti-patterns and common mistakes expert. Handles code review issues with clone abuse, unwrap in production, String misuse, index loops, and refactoring guidance. |
| metadata | {"triggers":["anti-pattern","common mistake","clone abuse","unwrap","code review","code smell","refactor","bad pattern"]} |
Top 5 Beginner Mistakes
| Rank | Mistake | Correct Approach |
|---|
| 1 | Using .clone() to escape borrow checker | Use references |
| 2 | Using .unwrap() in production code | Use ? or with_context() |
| 3 | Everything is String | Use &str, Cow<str> when needed |
| 4 | Index-based loops | Use iterators .iter(), .enumerate() |
| 5 | Fighting lifetimes | Redesign data structure |
Common Anti-Patterns
Anti-Pattern 1: Clone Everywhere
fn process(user: User) {
let name = user.name.clone();
}
fn process(user: &User) {
let name = &user.name;
}
When clone is actually needed:
- Truly need independent copy
- API design requires owned value
- Data flow requirements
Anti-Pattern 2: Unwrap in Production
let config = File::open("config.json").unwrap();
let config = File::open("config.json")?;
let config = File::open("config.json")
.context("failed to open config")?;
Anti-Pattern 3: String Everywhere
fn greet(name: String) {
println!("Hello, {}", name);
}
fn greet(name: &str) {
println!("Hello, {}", name);
}
Anti-Pattern 4: Index Loops
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);
}
Anti-Pattern 5: Excessive Unsafe
unsafe {
let ptr = data.as_mut_ptr();
}
let mut data: Vec<u8> = vec![0; size];
Solution Patterns
Pattern 1: Avoiding Clone
fn process_data(data: &Data) -> String {
let cloned = data.items.clone();
cloned.into_iter().map(|x| x.to_string()).collect()
}
fn process_data(data: &Data) -> String {
data.items.iter().map(|x| x.to_string()).collect()
}
Pattern 2: Proper Error Handling
fn load_config() -> Config {
let content = std::fs::read_to_string("config.toml").unwrap();
toml::from_str(&content).unwrap()
}
fn load_config() -> Result<Config, Box<dyn Error>> {
let content = std::fs::read_to_string("config.toml")?;
Ok(toml::from_str(&content)?)
}
fn load_config() -> anyhow::Result<Config> {
let content = std::fs::read_to_string("config.toml")
.context("failed to read config file")?;
toml::from_str(&content)
.context("failed to parse config")
}
Pattern 3: String vs &str
struct Config {
host: String,
port: String,
path: String,
}
impl Config {
fn new(host: String, port: String, path: String) -> Self {
Self { host, port, path }
}
}
impl Config {
fn new(host: impl Into<String>, port: u16, path: impl Into<String>) -> Self {
Self {
host: host.into(),
port: port.to_string(),
path: path.into(),
}
}
}
Pattern 4: Iterator-Based Processing
fn sum_even(nums: &[i32]) -> i32 {
let mut sum = 0;
for i in 0..nums.len() {
if nums[i] % 2 == 0 {
sum += nums[i];
}
}
sum
}
fn sum_even(nums: &[i32]) -> i32 {
nums.iter()
.filter(|&&n| n % 2 == 0)
.sum()
}
Code Smell Quick Reference
| Symptom | Indicates | Refactoring Direction |
|---|
Many .clone() | Unclear ownership | Clarify data flow |
Many .unwrap() | Missing error handling | Add Result handling |
Many pub fields | Broken encapsulation | Private + accessors |
| Deep nesting | Complex logic | Extract methods |
| Long functions (>50 lines) | Too many responsibilities | Split responsibilities |
| Huge enums | Missing abstraction | Trait + types |
Outdated โ Modern Patterns
| Outdated | Modern |
|---|
Index loop .items[i] | .iter().enumerate() |
collect::<Vec<_>>() then iterate | Chain iterators |
lazy_static! | std::sync::OnceLock |
mem::transmute conversion | as or TryFrom |
| Custom linked list | Vec or VecDeque |
| Manual unsafe cell | Cell, RefCell |
Workflow
Step 1: Identify Anti-Patterns
Code review checklist:
โ Lots of .clone()? Check ownership design
โ .unwrap() in lib code? Need error handling
โ Index loops? Should use iterators
โ pub fields with invariants? Need encapsulation
โ >50 line functions? Should split
Step 2: Ask Key Questions
1. Is this fighting Rust or working with Rust?
Fighting โ Redesign
Working with โ Continue
2. Is this clone necessary?
Escaping borrow checker โ Warning sign
Actually need copy โ Keep
3. Will this unwrap panic?
Might panic โ Use ?
Never panics โ expect("reason")
4. Is there a more idiomatic way?
Check std library patterns
Review other Rust code
Step 3: Refactor
Identified anti-pattern?
โ
Understand the root cause
โ
Find idiomatic alternative
โ
Refactor incrementally
โ
Test thoroughly
Review Checklist
When reviewing code:
Verification Commands
cargo clippy
cargo clippy -- -W clippy::clone_on_copy \
-W clippy::unwrap_used \
-W clippy::expect_used
cargo clippy -- -W clippy::cognitive_complexity
rg "TODO|FIXME|XXX|HACK" --type rust
Common Pitfalls
1. Clone to Compile
Symptom: Lots of .clone() calls
fn process(items: &Vec<Item>) -> Vec<String> {
let items_clone = items.clone();
items_clone.into_iter().map(|i| i.name).collect()
}
fn process(items: &[Item]) -> Vec<String> {
items.iter().map(|i| i.name.clone()).collect()
}
fn process(items: &[Item]) -> Vec<&str> {
items.iter().map(|i| i.name.as_str()).collect()
}
2. Error Handling Shortcuts
Symptom: Unwrap/expect in production code
let data = fetch_data().unwrap();
let parsed: Config = serde_json::from_str(&data).expect("bad JSON");
fn load_data() -> Result<Config, Box<dyn Error>> {
let data = fetch_data()?;
let parsed = serde_json::from_str(&data)?;
Ok(parsed)
}
3. String Allocation Waste
Symptom: Unnecessary String allocations
fn log_message(level: String, msg: String) {
println!("[{}] {}", level, msg);
}
fn log_message(level: &str, msg: &str) {
println!("[{}] {}", level, msg);
}
Self-Check Questions
1. Is this code fighting Rust?
- Fighting โ Redesign approach
- Working with โ Continue
2. Is this clone necessary?
- To escape borrow checker โ Warning sign
- Actually need independent copy โ OK
3. Will this unwrap panic?
- Might panic โ Use
?
- Never panics โ
expect("reason")
4. Is there a more idiomatic way?
- Reference other Rust codebases
- Check std library APIs
Related Skills
- rust-coding - Idiomatic patterns to follow
- rust-ownership - Understanding borrowing to avoid clones
- rust-error - Proper error handling patterns
- rust-performance - When optimization matters
- rust-refactoring - Systematic code improvement
Localized Reference
- Chinese version: SKILL_ZH.md - ๅฎๆดไธญๆ็ๆฌ๏ผๅ
ๅซๆๆๅ
ๅฎน