Result
El mecanismo primario para el manejo de errores en Rust es el enum Result, que vimos brevemente al discutir los tipos de la biblioteca estándar.
use std::fs::File;
use std::io::Read;
fn main() {
let file: Result<File, std::io::Error> = File::open("diary.txt");
match file {
Ok(mut file) => {
let mut contents = String::new();
if let Ok(bytes) = file.read_to_string(&mut contents) {
println!("Querido diario: {contents} ({bytes} bytes)");
} else {
println!("No se ha podido leer el contenido del archivo");
}
}
Err(err) => {
println!("No se ha podido abrir el diario: {err}");
}
}
}
-
Resulttiene dos variantes:Ok, que contiene el valor de éxito; yErr, que contiene un valor de error de algún tipo. -
La signatura de tipo de una función indica si puede producir un error, en este caso devolverá un valor
Result. -
Como con
Option, no hay manera de olvidarse de manejar un error: no puedes acceder el valor de éxito o el valor de error sin hacer coincidencia de patrones sobre elResultpara ver que variante tienes. Métodos comounwraphacen que sea mas fácil escribir código rápido-y-sucio que no maneja errores de una forma robusta, pero esto significa que siempre puedes ver en tu código donde no estas manejando errores de la manera propia.
Más información
Podria ayudar comparar el manejo de errores en Rust con las convenciones de manejo de errores de otros lenguajes que conocen los estudiantes.
Excepciones
-
Muchos lenguajes usan excepciones, e.g. C++, Java, Python.
-
En la mayoría de los lenguajes con excepciones, el hecho de que una función pueda o no lanzar una excepción no es visible como parte de su firma de tipo. Esto generalmente significa que no se puede saber al llamar a una función si esta puede lanzar una excepción o no.
-
Las excepciones generalmente desenrollan la pila de llamadas, propagándose hacia arriba hasta alcanzar un bloque
try. Un error que se origina en lo profundo de la pila de llamadas puede afectar a una función no relacionada más arriba.
Números de error
-
Algunos lenguajes hacen que las funciones devuelvan un número de error (u otro valor de error) de forma separada al valor de retorno exitoso de la función. Algunos ejemplos son C y Go.
-
Depending on the language it may be possible to forget to check the error value, in which case you may be accessing an uninitialized or otherwise invalid success value.