Un error es básicamente un comportamiento o evento inesperado que puede hacer que un programa produzca resultados no deseados o termine abruptamente. Los errores son cosas que nadie quiere en su programa. Los errores recuperables son aquellos que no hacen que el programa finalice abruptamente. Ejemplo: cuando intentamos recuperar un archivo que no está presente o no tenemos permiso para abrirlo.
La mayoría del lenguaje no distingue entre los dos errores y usa una clase de excepción para superarlos, mientras que Rust usa un tipo de datos Result <R,T> para manejar los errores recuperables y el pánico. macro para detener la ejecución del programa en caso de errores irrecuperables. Result<T,E> es un tipo de datos de enumeración con dos variantes OK y Err que se define de la siguiente manera:
enum Result<T, E> { Ok(T), Err(E), }
T y E son parámetros de tipo genérico donde T representa el tipo de valor que se devolverá en caso de éxito dentro de la variante Ok, y E representa el tipo de error que se devolverá en caso de falla dentro de la variante Err.
Rust
use std::fs::File; fn main() { let f = File::open("gfg.txt"); println!("{:?}",f); }
Producción
Err(Os { code: 2, kind: NotFound, message: "No such file or directory" })
Dado que el archivo gfg.txt no estaba allí, File devolvió la instancia de Err. Si se hubiera encontrado el archivo gfg.txt, se habría devuelto una instancia del archivo.
Si no se encuentra un archivo como en el caso anterior, será mejor si le pedimos al usuario que verifique el nombre del archivo, la ubicación del archivo o que proporcione las especificaciones del archivo una vez más o lo que requiera la situación.
Rust
use std::fs::File; fn main() { // file doesn't exist let f = File::open("gfg.txt"); match f { Ok(file)=> { println!("file found {:?}",file); }, Err(_error)=> { // replace it with whatever you want to do if file is not found println!("file not found \n"); } } }
Producción
file not found
En el programa anterior, básicamente coincide con el tipo de devolución del resultado y realiza la tarea en consecuencia.
Vamos a crear nuestros propios errores de acuerdo con la lógica empresarial. Supongamos que queremos producir un error si una persona menor de 18 años intenta solicitar una credencial de elector.
Rust
fn main(){ let result = eligible(13); match result { Ok(age)=>{ println!("Person eligible to vote with age={}",age); }, Err(msg)=>{ println!("{}",msg); } } } fn eligible(age:i32)->Result<i32,String> { if age>=18 { return Ok(age); } else { return Err("Not Eligible..Wait for some years".to_string()); } }
Producción
Not Eligible..Wait for some years
Si queremos abortar el programa después de que encuentre un error recuperable, ¡podríamos usar panic! macro y para simplificar el proceso, Rust proporciona dos métodos unwrap() y expect().
- Desenvolver()
Rust
use std::fs::File; fn main() { let f = File::open("gfg.txt").unwrap(); }
Producción
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', main.rs:17:14
El unwrap() llama al panic! macro en caso de que no se encuentre el archivo mientras devuelve la instancia del controlador de archivos si se encuentra el archivo. Aunque unwrap() hace que el programa sea más corto, cuando hay demasiados métodos unwrap() en nuestro programa, se vuelve un poco confuso qué método unwrap() se llama pánico. macro. Entonces necesitamos algo que pueda producir el mensaje personalizado. En ese caso, el método expect() viene al rescate.
- suponer()
Rust
use std::fs::File; fn main() { let f = File::open("hello.txt").expect("Failed to open gfg.txt"); }
Producción:
thread 'main' panicked at 'Failed to open gfg.txt: Os { code: 2, kind: NotFound, message: "No such file or directory" }', main.rs:17:14
¡Pasamos nuestro mensaje al pánico! macro a través del parámetro expect .