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(): Retornatruesi l'Optionconté un valor.is_none(): Retornatruesi l'Optionno 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.
