Option::or în Rust

Dacă opțiunea este None, încearcă altă opțiune; Some rămâne neschimbat. or_else calculează alternativa doar la nevoie.

Sintaxă
fn or(self, optb: Option<T>) -> Option<T>
fn or_else<F: FnOnce() -> Option<T>>(self, f: F) -> Option<T>

Ce face Option::or

or returnează opțiunea însăși dacă este Some, altfel returnează alternativa dată. Spre deosebire de unwrap_or, rezultatul rămâne un Option, deci alternativa poate lipsi și ea.

or_else primește o funcție care produce alternativa și o apelează doar dacă prima opțiune este None. Este forma potrivită pentru un șir de surse încercate pe rând: setarea din linia de comandă, apoi din fișier, apoi din mediu.

Parametri

Parametru Descriere
optb Alternativa (la or). Este calculată oricum, înainte de apel.
f Funcția care produce alternativa (la or_else). Este apelată doar pentru None.

Ce returnează

Prima opțiune dacă este Some; altfel alternativa (care poate fi tot None).

Exemple

Exemplul 1: Prima valoare disponibilă

Telefonul de serviciu lipsește, așa că se folosește cel personal. Dacă lipsesc ambele, rezultatul este None.

fn main() {
    let serviciu: Option<&str> = None;
    let personal: Option<&str> = Some("0722 111 222");

    println!("Contact Ana: {:?}", serviciu.or(personal));
    println!("Contact Dan: {:?}", None::<&str>.or(None));
    println!("Some rămâne: {:?}", Some("0233 000").or(personal));
}

Rezultat

Contact Ana: Some("0722 111 222")
Contact Dan: None
Some rămâne: Some("0233 000")

Exemplul 2: Surse încercate pe rând cu or_else

Fiecare sursă este consultată doar dacă cele dinainte nu au dat nimic; de aceea a treia sursă nu mai este întrebată.

fn din_argumente() -> Option<String> {
    println!("caut în argumente...");
    None
}

fn din_fisier() -> Option<String> {
    println!("caut în fișierul de configurare...");
    Some(String::from("Cluj"))
}

fn din_mediu() -> Option<String> {
    println!("caut în variabilele de mediu...");
    Some(String::from("Iași"))
}

fn main() {
    let oras = din_argumente().or_else(din_fisier).or_else(din_mediu);
    println!("Oraș ales: {oras:?}");
}

Rezultat

caut în argumente...
caut în fișierul de configurare...
Oraș ales: Some("Cluj")

Greșeli frecvente

  • Confunzi or cu unwrap_or: or primește și returnează Option; unwrap_or primește și returnează valoarea simplă.
  • Scrii a.or(cauta_in_baza_de_date()): căutarea rulează chiar dacă a este Some. Folosește or_else.

Comenzi înrudite

  • Option::unwrap_or: Scoate valoarea din Some sau, pentru None, folosește o valoare de rezervă: fixă, calculată de o funcție sau implicită.
  • 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.
  • Result::and_then: and_then continuă cu următorul pas care poate eșua doar dacă cel curent a reușit; or_else încearcă o recuperare la eroare.