Ce face Result::and_then
and_then aplică funcția pe valoarea din Ok; funcția returnează la rândul ei un Result. Prima eroare oprește lanțul și este returnată ca atare.
or_else este pentru partea de eroare: dacă rezultatul este Err(e), apelează funcția cu e, care poate „repara” situația (returnează Ok) sau poate da altă eroare. Pentru Ok, funcția nu este apelată.
Parametri
| Parametru | Descriere |
|---|---|
op |
La and_then: pasul următor, aplicat valorii. La or_else: recuperarea, aplicată erorii. |
Ce returnează
Un Result: rezultatul pasului următor, respectiv al recuperării.
Exemple
Exemplul 1: Validare în doi pași
Întâi transformăm textul în număr, apoi verificăm intervalul. Fiecare pas poate da eroare.
fn in_interval(n: i32) -> Result<i32, String> {
if (1..=10).contains(&n) {
Ok(n)
} else {
Err(format!("{n} nu este între 1 și 10"))
}
}
fn main() {
for t in ["7", "15", "x"] {
let r = t
.parse::<i32>()
.map_err(|e| e.to_string())
.and_then(in_interval);
println!("{t:?} -> {r:?}");
}
}
Rezultat
"7" -> Ok(7)
"15" -> Err("15 nu este între 1 și 10")
"x" -> Err("invalid digit found in string")
Exemplul 2: Recuperare cu or_else
Dacă textul nu este un număr întreg, încercăm să-l citim ca număr zecimal și îl rotunjim.
fn citeste(text: &str) -> Result<i64, String> {
text.parse::<i64>().or_else(|_| {
text.parse::<f64>()
.map(|f| f.round() as i64)
.map_err(|_| format!("„{text}” nu este număr"))
})
}
fn main() {
for t in ["12", "12.7", "doisprezece"] {
println!("{t:?} -> {:?}", citeste(t));
}
}
Rezultat
"12" -> Ok(12)
"12.7" -> Ok(13)
"doisprezece" -> Err("„doisprezece” nu este număr")
Greșeli frecvente
- Folosești
and_thencând tipurile de eroare diferă între pași: toate trebuie să aibă acelașiE. Unifică-le cumap_err. - Faci lanțuri lungi de
and_then. Într-o funcție care returneazăResult, varianta cu?pe fiecare linie este mai ușor de citit.
Comenzi înrudite
Result::map: map transformă valoarea din Ok și lasă eroarea neschimbată; map_err transformă eroarea și lasă valoarea neschimbată.Option::and_then: Leagă mai mulți pași care pot da None: aplică funcția doar pentru Some, iar funcția returnează la rândul ei un Option.Option::or: Dacă opțiunea este None, încearcă altă opțiune; Some rămâne neschimbat. or_else calculează alternativa doar la nevoie.Result: Tipul pentru operații care pot eșua: Ok(valoare) la succes sau Err(eroare) cu motivul eșecului.