Ce face for … in
for x in ceva funcționează cu orice valoare care se poate transforma într-un iterator: intervale (0..10), array-uri, vectori, HashMap, caracterele unui text (s.chars()) și orice iterator. Rust nu are bucla for (i = 0; i < n; i++) din C.
a..b merge de la a la b - 1, iar a..=b include și b. Pentru ordine inversă: (1..=10).rev(); pentru pași mai mari: (0..100).step_by(10).
Atenție la ce primește bucla: for x in v consumă vectorul (după buclă v nu mai poate fi folosit), for x in &v doar îl citește, iar for x in &mut v îți permite să modifici elementele cu *x. Pentru indice și valoare împreună, folosește .iter().enumerate().
Exemple
Exemplul 1: Intervale
1..=5 include 5. rev() inversează ordinea, iar step_by sare din 5 în 5.
fn main() {
for i in 1..=5 {
print!("{i} ");
}
println!();
for i in (1..=3).rev() {
print!("{i}... ");
}
println!("Start!");
let multipli: Vec<i32> = (0..=20).step_by(5).collect();
println!("{multipli:?}");
}
Rezultat
1 2 3 4 5
3... 2... 1... Start!
[0, 5, 10, 15, 20]
Exemplul 2: Prin referință, cu indice, și cu modificare
&elevi doar citește, deci vectorul poate fi folosit și după buclă. enumerate dă perechi (indice, element). &mut note permite modificarea fiecărei note prin *nota.
fn main() {
let elevi = vec!["Ana", "Mihai", "Ioana"];
for (i, nume) in elevi.iter().enumerate() {
println!("{}. {nume}", i + 1);
}
let mut note = vec![7, 8, 9];
for nota in &mut note {
*nota += 1;
}
println!("{} elevi, note mărite: {note:?}", elevi.len());
}
Rezultat
1. Ana
2. Mihai
3. Ioana
3 elevi, note mărite: [8, 9, 10]
Exemplul 3: Caracterele unui text
chars() dă caracterele unul câte unul, inclusiv cele cu diacritice.
fn main() {
let cuvant = "Brașov";
let mut vocale = 0;
for c in cuvant.chars() {
if "aeiouăâî".contains(c.to_ascii_lowercase()) {
vocale += 1;
}
}
println!("{cuvant} are {} caractere, dintre care {vocale} vocale", cuvant.chars().count());
}
Rezultat
Brașov are 6 caractere, dintre care 2 vocale
Greșeli frecvente
- Scrii
for x in vși apoi foloseștiv: eroareborrow of moved value, pentru că bucla a consumat vectorul. Scriefor x in &v. - Parcurgi după indice (
for i in 0..v.len()) doar ca să citeștiv[i]. Variantafor x in &vsau.iter().enumerate()este mai sigură și mai rapidă (fără verificarea indicelui). - Încerci să adaugi sau să ștergi elemente din vector în timp ce îl parcurgi. Compilatorul nu permite (vectorul este împrumutat de buclă); colectează modificările și aplică-le după buclă sau folosește
retain.
Comenzi înrudite
loop, break și continue: loop repetă un bloc la nesfârșit până la un break; break poate returna o valoare, iar continue sare la pasul următor al buclei.while: Repetă un bloc de cod cât timp o condiție bool rămâne adevărată; condiția este verificată înainte de fiecare pas.array ([T; N]): Un șir de lungime fixă, cunoscută la compilare, cu elemente de același tip, păstrat direct pe stivă.slice-uri (&[T] și &str): O „fereastră” spre o parte dintr-un array, Vec sau text: o referință care știe de unde începe și câte elemente are, fără să copieze nimic.closures și move: Funcții anonime, scrise cu |parametri|, care pot folosi variabilele din jur. move le dă proprietatea asupra acelor variabile.