Option::map în Rust

Transformă valoarea din Some cu o funcție și păstrează None neschimbat.

Sintaxă
fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U>

Ce face Option::map

map aplică o funcție pe valoarea din interior, fără să scoți valoarea afară. Some(x) devine Some(f(x)), iar None rămâne None, fără ca funcția să fie apelată.

Este util când vrei să lucrezi cu valoarea „dacă există” și să decizi abia la final ce faci cu lipsa ei. Tipul se poate schimba: din Option<&str> poți obține Option<usize> (lungimea textului).

Parametri

Parametru Descriere
f Funcția aplicată pe valoarea din Some. Primește valoarea (prin mutare) și returnează noua valoare.

Ce returnează

Some(f(x)) pentru Some(x); None pentru None.

Exemple

Exemplul 1: Calcul pe o valoare care poate lipsi

Prețul cu TVA se calculează doar dacă prețul există. La final, map și unwrap_or produc textul de afișat.

fn pret_produs(nume: &str) -> Option<f64> {
    match nume {
        "pâine" => Some(5.0),
        "lapte" => Some(7.5),
        _ => None,
    }
}

fn main() {
    for produs in ["pâine", "cafea", "lapte"] {
        let cu_tva = pret_produs(produs).map(|p| p * 1.19);
        let text = cu_tva
            .map(|p| format!("{p:.2} lei"))
            .unwrap_or(String::from("indisponibil"));
        println!("{produs}: {text}");
    }
}

Rezultat

pâine: 5.95 lei
cafea: indisponibil
lapte: 8.92 lei

Exemplul 2: Schimbarea tipului

split_once dă Option<(&str, &str)>; map păstrează doar partea de după @.

fn main() {
    let adrese = ["ana@dexblog.ro", "fara-arond", "mihai@exemplu.ro"];
    for adresa in adrese {
        let domeniu = adresa.split_once('@').map(|(_, d)| d);
        let lungime = domeniu.map(str::len);
        println!("{adresa}: domeniu = {domeniu:?}, lungime = {lungime:?}");
    }
}

Rezultat

ana@dexblog.ro: domeniu = Some("dexblog.ro"), lungime = Some(10)
fara-arond: domeniu = None, lungime = None
mihai@exemplu.ro: domeniu = Some("exemplu.ro"), lungime = Some(10)

Greșeli frecvente

  • Folosești map cu o funcție care returnează tot Option: obții Option<Option<U>>. În acest caz folosește and_then.
  • Folosești map doar pentru efecte (afișare): x.map(|v| println!("{v}")); dă avertismentul unused_must_use. Scrie if let Some(v) = x { ... }.

Comenzi înrudite

  • 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::filter: filter păstrează valoarea doar dacă respectă o condiție; is_some_and întreabă direct dacă există și respectă condiția.
  • Result::map: map transformă valoarea din Ok și lasă eroarea neschimbată; map_err transformă eroarea și lasă valoarea neschimbată.
  • Option::unwrap_or: Scoate valoarea din Some sau, pentru None, folosește o valoare de rezervă: fixă, calculată de o funcție sau implicită.