Iterator::for_each în Rust

Apelează o funcție pentru fiecare element; este echivalentul unei bucle for, scris la capătul unui lanț de adaptoare.

Sintaxă
fn for_each<F>(self, f: F)
where F: FnMut(Self::Item)

Ce face Iterator::for_each

it.for_each(|x| ...) face același lucru ca for x in it { ... }. Este comod la finalul unui lanț lung (.filter(..).map(..).for_each(..)), unde o buclă for ar cere o variabilă intermediară.

În closure nu poți folosi break, continue sau return din funcția exterioară (return doar trece la următorul element). Dacă ai nevoie de oprire timpurie, folosește o buclă for sau try_for_each, care se oprește la primul Err/None. Este un consumator: parcurge iteratorul (sau doar cât are nevoie) și pornește lanțul de adaptoare leneșe din fața lui.

Parametri

Parametru Descriere
f Closure apelat pentru fiecare element.

Ce returnează

Nimic (()).

Exemple

Exemplul 1: La capătul unui lanț

fn main() {
    let comenzi = [("Ana", 120), ("Mihai", 35), ("Ioana", 260), ("Radu", 80)];
    comenzi
        .iter()
        .filter(|(_, suma)| *suma >= 80)
        .map(|(nume, suma)| format!("{nume}: {suma} lei (livrare gratuită)"))
        .for_each(|linie| println!("{linie}"));
}

Rezultat

Ana: 120 lei (livrare gratuită)
Ioana: 260 lei (livrare gratuită)
Radu: 80 lei (livrare gratuită)

Exemplul 2: for_each față de for și try_for_each

try_for_each se oprește la primul Err, așa că „Radu” nu mai este procesat.

fn main() {
    let note = [9, 7, 10];
    note.iter().for_each(|n| print!("{n} "));
    println!();
    for n in &note {
        print!("{n} ");
    }
    println!();

    let elevi = ["Ana", "", "Radu"];
    let rezultat = elevi.iter().try_for_each(|nume| {
        if nume.is_empty() {
            return Err("nume lipsă");
        }
        println!("înscriu {nume}");
        Ok(())
    });
    println!("{:?}", rezultat);
}

Rezultat

9 7 10 
9 7 10 
înscriu Ana
Err("nume lipsă")

Greșeli frecvente

  • Încerci break în for_each: `break` inside of a closure. Folosește o buclă for sau try_for_each.
  • Folosești map pentru efecte (afișare) și uiți să consumi: nimic nu rulează. for_each este consumatorul pentru efecte.

Comenzi înrudite

  • Iterator::map: Transformă fiecare valoare a iteratorului cu o funcție și dă un iterator cu rezultatele; nu calculează nimic până la consumare.
  • Iterator::inspect: Apelează o funcție pe fiecare element care trece prin lanț, fără să-l schimbe; util pentru depanare.
  • Iterator::try_fold: Ca fold, dar funcția returnează Option sau Result și oprirea are loc la primul None sau Err.
  • IntoIterator: Trait-ul tipurilor care pot fi transformate într-un iterator; este ce folosește bucla for pentru a parcurge o valoare.