Ce face cargo clippy
Clippy este un „profesor” pentru codul Rust: compilează proiectul ca cargo check și aplică în plus peste 700 de reguli. Găsește bucle scrise greu (for i in 0..v.len()), comparații inutile (len() == 0 în loc de is_empty()), clonări inutile, posibile bug-uri și cod care poate fi simplificat.
Fiecare avertisment are un nume (de exemplu clippy::needless_range_loop), un link spre explicația regulii și, de obicei, o sugestie de cod. cargo clippy --fix aplică automat sugestiile sigure.
Regulile sunt grupate: clippy::all (implicit), clippy::pedantic (mai stricte), clippy::nursery (noi). O regulă se poate dezactiva local cu #[allow(clippy::nume)] sau pentru tot proiectul în secțiunea [lints.clippy] din Cargo.toml.
Exemple
Exemplul 1: Patru sfaturi pentru un program scurt
Codul se compilează fără avertismente obișnuite, dar Clippy găsește patru lucruri de îmbunătățit, fiecare cu soluția lui.
// src/main.rs
fn main() {
let note = vec![9, 7, 10];
let mut total = 0;
for i in 0..note.len() {
total = total + note[i];
}
if note.len() == 0 {
println!("Nicio notă");
}
println!("Total: {total}");
}
$ cargo clippy
Rezultat în terminal
Checking salut v0.1.0 (/home/ana/proiecte/salut)
warning: the loop variable `i` is only used to index `note`
--> src/main.rs:4:14
|
4 | for i in 0..note.len() {
| ^^^^^^^^^^^^^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.99.0/index.html#needless_range_loop
= note: `#[warn(clippy::needless_range_loop)]` on by default
help: consider using an iterator
|
4 - for i in 0..note.len() {
4 + for <item> in ¬e {
|
warning: manual implementation of an assign operation
--> src/main.rs:5:9
|
5 | total = total + note[i];
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `total += note[i]`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.99.0/index.html#assign_op_pattern
= note: `#[warn(clippy::assign_op_pattern)]` on by default
warning: length comparison to zero
--> src/main.rs:7:8
|
7 | if note.len() == 0 {
| ^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `note.is_empty()`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.99.0/index.html#len_zero
= note: `#[warn(clippy::len_zero)]` on by default
warning: useless use of `vec!`
--> src/main.rs:2:16
|
2 | let note = vec![9, 7, 10];
| ^^^^^^^^^^^^^^ help: you can use an array directly: `[9, 7, 10]`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.99.0/index.html#useless_vec
= note: `#[warn(clippy::useless_vec)]` on by default
warning: `salut` (bin "salut") generated 4 warnings (run `cargo clippy --fix --bin "salut" -p salut -- ` to apply 3 suggestions)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.41s
Exemplul 2: Codul după aplicarea sfaturilor
Aceeași logică, scrisă idiomatic. cargo clippy nu mai are nimic de semnalat, iar programul rulează la fel.
fn main() {
let note = [9, 7, 10];
let mut total = 0;
for nota in ¬e {
total += nota;
}
if note.is_empty() {
println!("Nicio notă");
}
println!("Total: {total}");
}
Rezultat
Total: 26
Greșeli frecvente
- Dezactivezi o regulă peste tot (
#![allow(clippy::all)]) pentru că un sfat pare inutil. Citește explicația din link; dacă nu se potrivește, dezactiveaz-o doar în locul respectiv. - Rulezi
cargo clippy --fixcu modificări nesalvate în git: Cargo refuză (working directory contains uncommitted changes), ca să nu amesteci modificările. Fă commit sau adaugă--allow-dirty.
Comenzi înrudite
cargo check: Verifică dacă proiectul se compilează (tipuri, borrow checker) fără să producă executabilul. Este mult mai rapid decât cargo build.cargo fmt: Formatează automat tot codul proiectului după stilul oficial Rust (indentare, spații, acolade), cu rustfmt.atribute (#[derive], #[cfg], #[allow]): Informații pentru compilator scrise cu #[…] deasupra unui element: generează cod (derive), aleg codul compilat (cfg) sau schimbă avertismentele.for … in: Parcurge pe rând fiecare element al unui interval, al unei colecții sau al unui iterator.