Option::as_ref în Rust

Transformă &Option<T> în Option<&T> (sau Option<&mut T>), ca să folosești valoarea fără să o muți din opțiune.

Sintaxă
fn as_ref(&self) -> Option<&T>
fn as_mut(&mut self) -> Option<&mut T>

Ce face Option::as_ref

Metode ca map, unwrap_or sau is_some_and consumă opțiunea (o mută). Dacă ai o Option<String> pe care vrei să o folosești și după, apelează-le pe opt.as_ref(): obții un Option<&String> care doar împrumută valoarea.

as_mut() dă un Option<&mut T>, prin care poți modifica valoarea din interior pe loc. Pentru Option<String> există și as_deref(), care dă direct Option<&str>.

Ce returnează

Some(&x) / Some(&mut x) pentru Some(x); None pentru None.

Exemple

Exemplul 1: Folosește valoarea fără să o muți

Fără as_ref(), map ar muta String-ul, iar ultimul println! nu ar compila.

fn main() {
    let email: Option<String> = Some(String::from("ana@dexblog.ro"));

    let lungime = email.as_ref().map(|e| e.len());
    let are_aron = email.as_ref().is_some_and(|e| e.contains('@'));

    println!("lungime = {lungime:?}, are @ = {are_aron}");
    println!("emailul este încă aici: {email:?}");
}

Rezultat

lungime = Some(14), are @ = true
emailul este încă aici: Some("ana@dexblog.ro")

Exemplul 2: Modificare pe loc cu as_mut

Adăugăm un punct la nota existentă. Pentru None, nu se întâmplă nimic.

fn main() {
    let mut note = [Some(8), None, Some(9)];
    for nota in note.iter_mut() {
        if let Some(n) = nota.as_mut() {
            *n += 1;
        }
    }
    println!("{note:?}");

    let mut nume: Option<String> = Some(String::from("ana"));
    if let Some(n) = nume.as_mut() {
        n.make_ascii_uppercase();
    }
    println!("{:?}", nume.as_deref());
}

Rezultat

[Some(9), None, Some(10)]
Some("ANA")

Greșeli frecvente

  • Primești eroarea value used after move după opt.map(...) sau opt.unwrap(). Pune .as_ref() înainte, dacă ai nevoie de opțiune și după.
  • Folosești as_ref() pe Option<String> și apoi te încurci cu &String; as_deref() dă direct &str.

Comenzi înrudite

  • Option::map: Transformă valoarea din Some cu o funcție și păstrează None neschimbat.
  • Option::take: take scoate valoarea și lasă None în loc; replace pune o valoare nouă și o returnează pe cea veche.
  • Option::copied: Transformă Option<&T> în Option<T> copiind valoarea; util după get() sau first() pe numere.
  • Option::filter: filter păstrează valoarea doar dacă respectă o condiție; is_some_and întreabă direct dacă există și respectă condiția.