Option::ok_or în Rust

Transformă un Option în Result: Some(x) devine Ok(x), iar None devine Err cu eroarea dată.

Sintaxă
fn ok_or<E>(self, err: E) -> Result<T, E>
fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E>

Ce face Option::ok_or

Un Option spune doar că valoarea lipsește, nu și de ce. ok_or(eroare) îl transformă într-un Result: Some(x) devine Ok(x), None devine Err(eroare).

Cel mai des îl folosești într-o funcție care returnează Result, urmat de ?: let nota = note.get(nume).ok_or("elev necunoscut")?;. ok_or_else construiește eroarea doar dacă este nevoie (de exemplu un format! cu detalii).

Parametri

Parametru Descriere
err La ok_or: eroarea pusă în Err. La ok_or_else: funcția care o construiește.

Ce returnează

Ok(x) pentru Some(x); Err(err) pentru None.

Exemple

Exemplul 1: Mesaj de eroare pentru o valoare lipsă

ok_or_else construiește un mesaj cu numele căutat; operatorul ? returnează eroarea mai departe.

use std::collections::BTreeMap;

fn nota(catalog: &BTreeMap<&str, u8>, nume: &str) -> Result<u8, String> {
    let n = catalog
        .get(nume)
        .copied()
        .ok_or_else(|| format!("{nume} nu este în catalog"))?;
    Ok(n)
}

fn main() {
    let catalog = BTreeMap::from([("Ana", 10), ("Mihai", 8)]);
    println!("{:?}", nota(&catalog, "Ana"));
    println!("{:?}", nota(&catalog, "Radu"));
}

Rezultat

Ok(10)
Err("Radu nu este în catalog")

Exemplul 2: ok_or cu o eroare fixă

Pentru o eroare simplă, fără calcule, ok_or este suficient.

fn primul_cuvant(text: &str) -> Result<&str, &'static str> {
    text.split_whitespace().next().ok_or("textul este gol")
}

fn main() {
    println!("{:?}", primul_cuvant("Bună ziua, Iași"));
    println!("{:?}", primul_cuvant("   "));
}

Rezultat

Ok("Bună")
Err("textul este gol")

Greșeli frecvente

  • Scrii ok_or(format!(...)): textul se construiește și când valoarea există. Folosește ok_or_else(|| format!(...)).
  • Încerci să folosești ? direct pe un Option într-o funcție care returnează Result: nu compilează. Transformă întâi cu ok_or.

Comenzi înrudite

  • Result::ok: Transformă un Result în Option: ok() păstrează valoarea și pierde eroarea; err() păstrează eroarea.
  • Option: Tipul care spune „poate există o valoare, poate nu”: Some(valoare) sau None, în locul lui null din alte limbaje.
  • Result: Tipul pentru operații care pot eșua: Ok(valoare) la succes sau Err(eroare) cu motivul eșecului.
  • Option::unwrap_or: Scoate valoarea din Some sau, pentru None, folosește o valoare de rezervă: fixă, calculată de o funcție sau implicită.