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:
Some(T)
: Representa un valor present de tipusT
.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()
: Retornatrue
si l'Option
conté un valor.is_none()
: Retornatrue
si l'Option
no conté cap valor.unwrap()
: Retorna el valor contingut si existeix, o pànic si ésNone
.unwrap_or(default)
: Retorna el valor contingut o un valor per defecte si ésNone
.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
.