Lecciones del módulo (2/2)
Pattern matching, Option y Result
Rust posee un mecanismo de control de flujo extremadamente potente llamado pattern matching (coincidencia de patrones). Permite comparar un valor con una serie de patrones y ejecutar código en función del patrón coincidente.
La Instrucción match
La instrucción match en Rust es similar a switch en otros lenguajes, pero mucho más potente y segura. El compilador garantiza que el emparejamiento sea exhaustivo, lo que significa que se gestionan todos los casos posibles:
enum Direction {
North,
South,
East,
West,
}
let dir = Direction::East;
match dir {
Direction::North => println!("Andiamo a Nord"),
Direction::South => println!("Andiamo a Sud"),
Direction::East => println!("Andiamo a Est"),
Direction::West => println!("Andiamo a Ovest"),
}
Manejo de la ausencia de valor: Option
Rust no tiene el concepto de valor nulo (null o nil). En su lugar, la biblioteca estándar define un enum llamado Option<T> que puede contener:
Some(T): contiene un valor de tipoT.None: indica la ausencia de valor.
let x: Option<i32> = Some(5);
let y: Option<i32> = None;
match x {
Some(val) => println!("C'e un valore: {}", val),
None => println!("Nessun valore trovato"),
}
Manejo de errores recuperables: Result
Para operaciones que pueden fallar (como la lectura de un archivo o la conversión de una cadena en un número), Rust usa el enum Result<T, E> que posee dos variantes:
Ok(T): la operación fue exitosa y contiene el valor de éxitoT.Err(E): la operación falló y contiene el errorE.
fn divide(numerator: f64, denominator: f64) -> Result<f64, String> {
if denominator == 0.0 {
Err(String::from("Divisione per zero!"))
} else {
Ok(numerator / denominator)
}
}
Gracias al compilador de Rust, estás obligado a manejar el caso Err antes de poder acceder al valor dentro de Ok, lo que evita muchos errores (bugs) en tiempo de ejecución.
El Patrón Comodín _ (Wildcard)
Cuando trabajamos con tipos de datos que tienen una gran cantidad de variantes (como los enteros), enumerar todos los casos en un match es imposible. Rust permite usar el carácter comodín _ para capturar todos los casos restantes que no se hayan definido explícitamente:
let some_u8 = 3u8;
match some_u8 {
1 => println!("Uno"),
2 => println!("Due"),
_ => println!("Qualcos'altro"), // Gestisce tutti gli altri valori
}
Pruébalo tú
Declara una variable maybe_value de tipo Option<i32> que contenga Some(42). Usa una instrucción match sobre maybe_value: si contiene Some(v) imprime 'value is: v' (con println!), si contiene None imprime 'no value'.
Mostrar pista
Escribe un bloque `match maybe_value { Some(v) => println!('value is: {}', v), None => println!('no value') }`.
Solución disponible después de 3 intentos
Completa la función check_age de modo que devuelva Ok('Adult') si age es mayor o igual a 18, o Err('Minor') en caso contrario.
Mostrar pista
Usa un `if age >= 18`para decidir si devolver`Ok('Adult')`o`Err('Minor')`.
Solución disponible después de 3 intentos
Declara un enum llamado Status que contenga las variantes Active e Inactive. En el main, declara una variable current_status con el valor Status::Active. Por último, usa una instrucción match sobre current_status para imprimir 'active' si el estado es Active, o 'inactive' si el estado es Inactive.
Mostrar pista
Define el enum antes del main con `enum Status { Active, Inactive }`. En el main usa `let current_status = Status::Active;`y realiza el`match` sobre las variantes.
Solución disponible después de 3 intentos