Common Rust Anti-Patterns and How to Avoid Them
Avoid common Rust anti-patterns by using Result for recoverable errors, Option for missing values, and iterators instead of manual loops.
// Anti-pattern: Using panic! for recoverable errors
fn divide_panic(a: i32, b: i32) -> i32 {
if b == 0 {
panic!("Cannot divide by zero");
}
a / b
}
// Correct: Return Result for error handling
fn divide(a: i32, b: i32) -> Result<i32, String> {
if b == 0 {
return Err("Cannot divide by zero".to_string());
}
Ok(a / b)
}
// Anti-pattern: Manual loop for iteration
fn sum_manual(numbers: &[i32]) -> i32 {
let mut sum = 0;
for x in numbers {
sum += x;
}
sum
}
// Correct: Use iterators for clarity and safety
fn sum_iter(numbers: &[i32]) -> i32 {
numbers.iter().sum()
}
fn main() {
let numbers = vec![1, 2, 3, 4, 5];
// Demonstrate the functions
println!("Manual sum: {}", sum_manual(&numbers));
println!("Iterator sum: {}", sum_iter(&numbers));
// Demonstrate divide
match divide(10, 2) {
Ok(res) => println!("10 / 2 = {}", res),
Err(e) => println!("Error: {}", e),
}
match divide(10, 0) {
Ok(res) => println!("10 / 0 = {}", res),
Err(e) => println!("Error: {}", e),
}
}