En aquest tema, aprendrem com gestionar errors en Rust utilitzant el tipus Option. El tipus Option és una eina poderosa que ens permet representar valors opcionals, és a dir, valors que poden o no estar presents. Això és especialment útil per evitar errors comuns com els punters nuls.

Què és Option?

El tipus Option és una enumeració que es defineix de la següent manera:

enum Option<T> {
    Some(T),
    None,
}
  • Some(T): Representa un valor present de tipus T.
  • None: Representa l'absència de valor.

Ús bàsic de Option

Creació d'un Option

fn main() {
    let some_number = Some(5);
    let some_string = Some("Hello");

    let absent_number: Option<i32> = None;
}

Accés al valor de Option

Per accedir al valor emmagatzemat dins d'un Option, podem utilitzar el patró de coincidència (match):

fn main() {
    let some_number = Some(5);

    match some_number {
        Some(value) => println!("El valor és: {}", value),
        None => println!("No hi ha cap valor"),
    }
}

Mètodes útils de Option

Rust proporciona diversos mètodes per treballar amb Option de manera més còmoda:

  • is_some(): Retorna true si l'Option conté un valor.
  • is_none(): Retorna true si l'Option no conté cap valor.
  • unwrap(): Retorna el valor contingut si existeix, o pànic si és None.
  • unwrap_or(default): Retorna el valor contingut o un valor per defecte si és None.
  • map(): Aplica una funció al valor contingut si existeix.

Exemple pràctic

Suposem que tenim una funció que busca un element en un vector i retorna un Option:

fn find_element(vec: &Vec<i32>, target: i32) -> Option<usize> {
    for (index, &element) in vec.iter().enumerate() {
        if element == target {
            return Some(index);
        }
    }
    None
}

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];

    match find_element(&numbers, 3) {
        Some(index) => println!("Element trobat a l'índex: {}", index),
        None => println!("Element no trobat"),
    }
}

Exercicis Pràctics

Exercici 1: Cerca en un Vector

Escriu una funció find_string que cerqui una cadena en un vector de cadenes i retorni un Option amb l'índex de la cadena si es troba, o None si no es troba.

fn find_string(vec: &Vec<&str>, target: &str) -> Option<usize> {
    // Implementa la funció aquí
}

fn main() {
    let strings = vec!["apple", "banana", "cherry"];

    match find_string(&strings, "banana") {
        Some(index) => println!("Cadena trobada a l'índex: {}", index),
        None => println!("Cadena no trobada"),
    }
}

Solució

fn find_string(vec: &Vec<&str>, target: &str) -> Option<usize> {
    for (index, &element) in vec.iter().enumerate() {
        if element == target {
            return Some(index);
        }
    }
    None
}

fn main() {
    let strings = vec!["apple", "banana", "cherry"];

    match find_string(&strings, "banana") {
        Some(index) => println!("Cadena trobada a l'índex: {}", index),
        None => println!("Cadena no trobada"),
    }
}

Exercici 2: Divisió Segura

Escriu una funció safe_divide que prengui dos enters i retorni un Option<f64>. Si el divisor és zero, ha de retornar None. En cas contrari, ha de retornar el resultat de la divisió com a Some.

fn safe_divide(a: i32, b: i32) -> Option<f64> {
    // Implementa la funció aquí
}

fn main() {
    match safe_divide(10, 2) {
        Some(result) => println!("Resultat: {}", result),
        None => println!("No es pot dividir per zero"),
    }

    match safe_divide(10, 0) {
        Some(result) => println!("Resultat: {}", result),
        None => println!("No es pot dividir per zero"),
    }
}

Solució

fn safe_divide(a: i32, b: i32) -> Option<f64> {
    if b == 0 {
        None
    } else {
        Some(a as f64 / b as f64)
    }
}

fn main() {
    match safe_divide(10, 2) {
        Some(result) => println!("Resultat: {}", result),
        None => println!("No es pot dividir per zero"),
    }

    match safe_divide(10, 0) {
        Some(result) => println!("Resultat: {}", result),
        None => println!("No es pot dividir per zero"),
    }
}

Resum

En aquesta secció, hem après com utilitzar el tipus Option per gestionar errors i valors opcionals en Rust. Hem vist com crear i accedir a valors Option, així com alguns mètodes útils per treballar amb Option. També hem practicat amb exercicis per reforçar els conceptes apresos. En la següent secció, explorarem la gestió d'errors amb el tipus Result.

© Copyright 2024. Tots els drets reservats