Algoritmos y Estructuras de Datos Herramientas Lenguaje de programación
!Prog C/C++ Rust
Linux Matemáticas
Mates Discretas
Programación Orientada a Objetos Sistemas Operativos

Errores en Rust


[words: 355] [reading time: 2min] [size: 15160 bytes]

Errores irrecuperables

Para crear errores que paren completamente la ejecución del programa usamos el macro panic!(). Entre los paréntesis podemos dar una pequeña descripción del problema, con la sintaxis del macro format!() (o println!()).

Errores recuperables

Para otros errores donde una operación pudo acabar de forma exitosa, usamos la enum Result:

1enum Result<T, E> {
2    Ok(T),
3    Err(E),
4}

La variante Ok guarda el resultado de la función en caso de que la operación fuese exitosa. Sino, se provee un error con la variante Err.

Podemos manejar el error de la siguiente forma:

 1let f = match File::open("hello.txt") {
 2    Ok(file) => file,
 3    Err(error) => match error.kind() {
 4        ErrorKind::NotFound => match File::create("hello.txt") {
 5            Ok(fc) => fc,
 6            Err(e) => panic!("Problem creating the file: {:?}", e),
 7        },
 8        other_error => {
 9            panic!("Problem opening the file: {:?}", other_error)
10        }
11    },
12};

Para evitar tanta expresión match podemos usar la función unwrap_or_else(), que devuelve el valor en caso de éxito y ejecuta la función que le demos de parámetro en caso de error:

1let f = File::open("hello.txt").unwrap_or_else(|error| {
2    if error.kind() == ErrorKind::NotFound {
3        File::create("hello.txt").unwrap_or_else(|error| {
4            panic!("Problem creating the file: {:?}", error);
5        })
6    } else {
7        panic!("Problem opening the file: {:?}", error);
8    }
9});

De igual forma esto es muy largo para escribir, y sobre todo si estamos probando. Para eso tenemos otras funciones que nos simplifican más el trabajo.

Para simplificar más, y en el caso de estar escribiendo una función que puede dar un error o no, podemos simplemente propagarlo, que sería devolverlo para que el que use esta función se encargue del error. Podemos devolver el error manualmente o usar el operador ?:

1fn foo() -> Result<(), some_error> {
2    let v = function_that_might_fail()?;
3    // this is equivalent to:
4    let v = match function_that_might_fail() {
5        Ok(value)  => value,
6        Err(error) => return Err(error),
7    }
8}
Anterior: Memoria Volver a Rust Siguiente: Generics, traits y closures