Ce face Iterator::try_fold
try_fold funcționează ca fold, cu o diferență: closure-ul returnează Option<B> sau Result<B, E>. Cât timp primește Some / Ok, continuă cu valoarea din ele. La primul None sau Err, se oprește imediat și returnează acel rezultat; elementele rămase nu mai sunt procesate.
Este potrivit pentru calcule care pot eșua: adunare cu verificare de depășire (checked_add), parsare, validare. Primește iteratorul prin &mut, deci după o oprire timpurie poți continua de unde a rămas.
Parametri
| Parametru | Descriere |
|---|---|
init |
Valoarea inițială. |
f |
Closure care returnează Some(acc)/Ok(acc) pentru a continua sau None/Err(e) pentru a opri. |
Ce returnează
Some(acc) / Ok(acc) dacă totul a reușit, altfel primul None / Err.
Exemple
Exemplul 1: Suma fără depășire
u8 merge doar până la 255. checked_add dă None la depășire, iar try_fold se oprește.
fn main() {
let mici: [u8; 3] = [100, 50, 60];
let mari: [u8; 3] = [100, 150, 60];
println!("{:?}", mici.iter().try_fold(0u8, |acc, &x| acc.checked_add(x)));
println!("{:?}", mari.iter().try_fold(0u8, |acc, &x| acc.checked_add(x)));
}
Rezultat
Some(210)
None
Exemplul 2: Totalul unui coș, cu eroare la primul preț greșit
fn total(preturi: &[&str]) -> Result<u32, String> {
preturi.iter().try_fold(0, |acc, p| {
let valoare: u32 = p.parse().map_err(|_| format!("preț invalid: {p:?}"))?;
Ok(acc + valoare)
})
}
fn main() {
println!("{:?}", total(&["12", "30", "8"]));
println!("{:?}", total(&["12", "treizeci", "8"]));
}
Rezultat
Ok(50)
Err("preț invalid: \"treizeci\"")
Greșeli frecvente
- Folosești
foldși verifici eroarea abia la final: continui inutil după primul eșec.try_foldse oprește imediat. - Uiți să înfășori rezultatul: closure-ul trebuie să returneze
Some(acc)sauOk(acc), nu doaracc.
Comenzi înrudite
Iterator::fold: Combină toate elementele într-o singură valoare, pornind de la o valoare inițială și aplicând o funcție pas cu pas.Iterator::scan: Ca fold, dar produce câte un rezultat după fiecare element: o stare actualizată pas cu pas, de exemplu un total cumulat.Iterator::collect: Consumă iteratorul și adună valorile într-o colecție: Vec, String, HashMap, HashSet, chiar Result sau Option.Iterator::sum: sum adună toate elementele, product le înmulțește; tipul rezultatului trebuie precizat.