Skip to main content
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() or expect() can cause your program to panic. Use proper error handling with ? operator and Result types in production code.
Unnecessary clones can hurt performance. Use references, slices, and ownership semantics to minimize cloning.
Rust’s iterators are powerful, expressive, and often more efficient than manual loops. Use them whenever possible.
Use &str for function parameters when you only need to read the string data, not own or modify it.
Define custom error types that implement the Error trait for better error handling and more context.
Write clear, idiomatic Rust code first, then optimize only after profiling identifies bottlenecks.
Use Cargo features for optional functionality and configuration instead of hardcoding or using environment variables.
Use unsafe only when necessary and document why it’s needed. Prefer safe abstractions whenever possible.
Use explicit lifetime annotations to express the relationship between references in your code.
Leverage Rust’s rich type system with enums, structs, and pattern matching to make invalid states unrepresentable.
Use Option for values that might be absent and Result for operations that might fail, rather than sentinel values or exceptions.
Run cargo clippy regularly and address its warnings. Clippy catches many common mistakes and anti-patterns.
Use Rust’s module system to organize code into logical units with clear public interfaces.
Use Rust’s built-in testing framework with #[test] attributes for unit tests and integration tests.
For larger projects, use Cargo workspaces to split your code into multiple crates with clear dependencies.
Use Rust’s concurrency features correctly, including channels, mutexes, and thread pools. Consider using the Rayon crate for parallel iterators.
Version control Cargo.lock for binary projects to ensure reproducible builds, but ignore it for libraries.
Use Rust’s documentation comments (///) to document your code, including examples that can be tested with cargo test --doc.