Iterator::inspect în Rust

Apelează o funcție pe fiecare element care trece prin lanț, fără să-l schimbe; util pentru depanare.

Sintaxă
fn inspect<F>(self, f: F) -> Inspect<Self, F>
where F: FnMut(&Self::Item)

Ce face Iterator::inspect

inspect(|x| ...) primește o referință la fiecare element, face ceva cu ea (de obicei îl afișează) și lasă elementul să treacă mai departe neschimbat. Pus între adaptoare, îți arată exact ce ajunge în fiecare etapă a lanțului.

Este și o demonstrație bună a lenei iteratorilor: mesajele apar intercalat, element cu element, nu etapă cu etapă, pentru că fiecare element trece prin tot lanțul înainte să vină următorul.

Parametri

Parametru Descriere
f Closure care primește &element.

Ce returnează

Un iterator Inspect cu aceleași elemente.

Exemple

Exemplul 1: Ce trece prin fiecare etapă

Ordinea mesajelor arată că elementele parcurg lanțul unul câte unul: 1 trece complet înainte ca 2 să intre.

fn main() {
    let suma: i32 = [1, 2, 3, 4]
        .into_iter()
        .inspect(|x| println!("intră:        {x}"))
        .filter(|x| x % 2 == 0)
        .inspect(|x| println!("  trece filtrul: {x}"))
        .map(|x| x * 10)
        .inspect(|x| println!("  după map:      {x}"))
        .sum();
    println!("suma: {suma}");
}

Rezultat

intră:        1
intră:        2
  trece filtrul: 2
  după map:      20
intră:        3
intră:        4
  trece filtrul: 4
  după map:      40
suma: 60

Exemplul 2: Numărarea liniilor ignorate

fn main() {
    let date = "12\nabc\n7\n\n30";
    let mut ignorate = 0;
    let numere: Vec<u32> = date
        .lines()
        .inspect(|l| {
            if l.parse::<u32>().is_err() {
                ignorate += 1;
            }
        })
        .filter_map(|l| l.parse().ok())
        .collect();
    println!("numere: {:?}, linii ignorate: {ignorate}", numere);
}

Rezultat

numere: [12, 7, 30], linii ignorate: 2

Greșeli frecvente

  • Încerci să modifici elementul în inspect: primești doar &T. Pentru transformări folosește map.
  • Lași inspect-uri de depanare în cod: afișarea încetinește și umple ieșirea. Șterge-le după ce ai găsit problema.

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::for_each: Apelează o funcție pentru fiecare element; este echivalentul unei bucle for, scris la capătul unui lanț de adaptoare.
  • Iterator: Trait-ul care descrie orice șir de valori produse pe rând: next() dă următoarea valoare, sau None la final.
  • Iterator::filter: Păstrează doar elementele pentru care condiția dată returnează true; restul sunt sărite.