Ce face Option
Rust nu are null. Când o valoare poate lipsi (căutarea unui elev după nume, primul element al unui vector gol, un câmp opțional), funcția returnează Option<T>. Valoarea este fie Some(x), adică există și este x, fie None, adică lipsește.
Compilatorul nu te lasă să folosești direct valoarea din Some: trebuie să tratezi și cazul None. Cel mai clar faci asta cu match sau cu if let Some(x) = .... Pentru o întrebare simplă de tip da/nu există is_some() (este Some?) și is_none() (este None?).
Option, Some și None sunt incluse automat în orice program (fac parte din prelude), deci nu ai nevoie de use.
Parametri
| Parametru | Descriere |
|---|---|
T |
Tipul valorii care poate lipsi: Option<i32>, Option<String>, Option<&str> etc. |
Ce returnează
is_some() returnează true pentru Some(_); is_none() returnează true pentru None.
Exemple
Exemplul 1: O funcție care poate să nu găsească nimic
cauta_nota returnează Some(nota) dacă elevul există și None altfel. match tratează ambele cazuri.
fn cauta_nota(nume: &str) -> Option<u8> {
match nume {
"Ana" => Some(10),
"Mihai" => Some(8),
_ => None,
}
}
fn main() {
for elev in ["Ana", "Ioana", "Mihai"] {
match cauta_nota(elev) {
Some(nota) => println!("{elev} are nota {nota}"),
None => println!("{elev} nu are încă notă"),
}
}
}
Rezultat
Ana are nota 10
Ioana nu are încă notă
Mihai are nota 8
Exemplul 2: is_some, is_none și if let
Metodele din std returnează și ele Option: first() pe un vector gol dă None. Cu {:?} vezi exact ce conține opțiunea.
fn main() {
let orase = vec!["Iași", "Cluj", "Brașov"];
let goale: Vec<&str> = Vec::new();
let primul = orase.first();
let nimic = goale.first();
println!("primul = {primul:?}, is_some = {}", primul.is_some());
println!("nimic = {nimic:?}, is_none = {}", nimic.is_none());
if let Some(oras) = orase.get(2) {
println!("Al treilea oraș: {oras}");
}
if orase.get(10).is_none() {
println!("Nu există poziția 10");
}
}
Rezultat
primul = Some("Iași"), is_some = true
nimic = None, is_none = true
Al treilea oraș: Brașov
Nu există poziția 10
Greșeli frecvente
- Încerci să folosești direct valoarea:
let n: u8 = cauta_nota("Ana");nu compilează, pentru că rezultatul esteOption<u8>, nuu8. Scoate valoarea cumatch,if let,unwrap_orsau?. - Scrii
if x.is_some() { let v = x.unwrap(); ... }. Merge, darif let Some(v) = x { ... }face același lucru mai scurt și fără risc de panică. - Folosești o valoare specială (0, -1, șir gol) pentru „lipsă”. În Rust,
Optionface lipsa vizibilă în tip și compilatorul te obligă să o tratezi.
Comenzi înrudite
Option::unwrap: Scoate valoarea din Some; pentru None programul se oprește cu panică. expect face la fel, cu mesajul tău.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::map: Transformă valoarea din Some cu o funcție și păstrează None neschimbat.Option::ok_or: Transformă un Option în Result: Some(x) devine Ok(x), iar None devine Err cu eroarea dată.Result: Tipul pentru operații care pot eșua: Ok(valoare) la succes sau Err(eroare) cu motivul eșecului.