Rust is a systems programming language focused on safety, speed, and concurrency. It enforces memory safety without using garbage collection, making it ideal for performance-critical applications.
Rust Anti-Patterns Overview
Rust, despite its focus on safety and correctness, still has common anti-patterns that can lead to bugs, performance issues, and maintenance problems. Here are the most important anti-patterns to avoid when writing Rust code.
Using unwrap() and expect() in Production Code
Using unwrap()
or expect()
can cause your program to panic. Use proper error handling with ?
operator and Result
types in production code.
Overusing Clones
Unnecessary clones can hurt performance. Use references, slices, and ownership semantics to minimize cloning.
Not Using Iterators
Rust’s iterators are powerful, expressive, and often more efficient than manual loops. Use them whenever possible.
Using String When &str Would Suffice
Use &str
for function parameters when you only need to read the string data, not own or modify it.
Not Using Proper Error Types
Define custom error types that implement the Error
trait for better error handling and more context.
Premature Optimization
Write clear, idiomatic Rust code first, then optimize only after profiling identifies bottlenecks.
Not Using Cargo Features
Use Cargo features for optional functionality and configuration instead of hardcoding or using environment variables.
Excessive Use of Unsafe
Use unsafe
only when necessary and document why it’s needed. Prefer safe abstractions whenever possible.
Not Using Lifetimes Correctly
Use explicit lifetime annotations to express the relationship between references in your code.
Not Using Rust's Type System
Leverage Rust’s rich type system with enums, structs, and pattern matching to make invalid states unrepresentable.
Not Using Option and Result
Use Option
for values that might be absent and Result
for operations that might fail, rather than sentinel values or exceptions.
Ignoring Clippy Warnings
Run cargo clippy
regularly and address its warnings. Clippy catches many common mistakes and anti-patterns.
Not Using Rust's Module System
Use Rust’s module system to organize code into logical units with clear public interfaces.
Not Using Rust's Testing Framework
Use Rust’s built-in testing framework with #[test]
attributes for unit tests and integration tests.
Not Using Cargo Workspaces
For larger projects, use Cargo workspaces to split your code into multiple crates with clear dependencies.
Not Using Rust's Concurrency Features Correctly
Use Rust’s concurrency features correctly, including channels, mutexes, and thread pools. Consider using the Rayon crate for parallel iterators.
Not Using Cargo.lock Correctly
Version control Cargo.lock for binary projects to ensure reproducible builds, but ignore it for libraries.
Not Using Rust's Documentation Features
Use Rust’s documentation comments (///
) to document your code, including examples that can be tested with cargo test --doc
.