Saltar al contenido principal
eLearner.app
Módulo 7 · Lección 2 de 214/14 en el curso~15 min
Lecciones del módulo (2/2)

Gestión de errores y el operador ?

La filosofía de Rust fomenta reconocer explícitamente la posibilidad de errores y estructurar el código para manejarlos antes de compilar el programa.

Los errores en Rust se dividen en dos categorías principales: errores irrecuperables (que provocan un bloqueo inmediato mediante el pánico panic!) y errores recuperables (manejados mediante el tipo Result<T, E>).


El tipo Resultado<T, E> y la coincidencia de patrones

La mayoría de los errores recuperables devuelven un tipo Result<T, E> que es una enumeración definida como:

Code
enum Result<T, E> {
    Ok(T),
    Err(E),
}

Podemos usar la coincidencia de patrones para inspeccionar el resultado:

Code
use std::fs::File;

fn main() {
    let greeting_file_result = File::open("hello.txt");

    let greeting_file = match greeting_file_result {
        Ok(file) => file,
        Err(error) => panic!("Problema nell'aprire il file: {:?}", error),
    };
}

Propagación de errores con el operador ?

Cuando implementamos una función, en lugar de manejar el error directamente dentro de ella, a menudo queremos devolver el error a la persona que llama para que pueda decidir qué hacer. Este proceso se llama propagación de errores.

Rust proporciona el operador ? como atajo sintáctico para la propagación de errores. Si el valor de Result es Ok, la expresión devuelve el valor dentro de Ok; si es Err, toda la función actual devuelve el error Err como si hubiéramos usado un return Err(...).

Code
use std::fs::File;
use std::io::{self, Read};

fn read_username_from_file() -> Result<String, io::Error> {
    let mut username_file = File::open("username.txt")?;
    let mut username = String::new();
    username_file.read_to_string(&mut username)?;
    Ok(username)
}

[!IMPORTANTE] El operador ? solo se puede utilizar en funciones que devuelven un tipo compatible con el valor al que se aplica (normalmente Result, Option o tipos que implementan FromResidual).


Errores personalizados

Podemos definir nuestros propios tipos de error implementando el rasgo std::fmt::Display (y opcionalmente std::error::Error) para proporcionar una representación del error legible por humanos:

Code
use std::fmt;

#[derive(Debug)]
struct MyError {
    details: String,
}

impl fmt::Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Errore: {}", self.details)
    }
}

impl std::error::Error for MyError {}

Pruébalo tú mismo

Ejercicio 1: Leer un archivo con ? operador

Ejercicio#rust.m7.l2.e1
Intentos: 0Cargando...

Complete la función read_username_from_file para usar ? operador. para propagar los errores generados al abrir el archivo y leer su contenido en la cadena del nombre de usuario.

Cargando editor...
Mostrar pista

Agregue el carácter `?` después de `File::open(...)` y después de `username_file.read_to_string(...)` para propagar errores.

Solución disponible después de 3 intentos

Ejercicio 2: Analizar y procesar un número

Ejercicio#rust.m7.l2.e2
Intentos: 0Cargando...

Escriba una función llamada parse_and_double que tome como entrada una referencia de cadena &str y devuelva un Resultado<i32, std::num::ParseIntError>. La función debe analizar la cadena con val.parse::<i32>() usando ? para propagar el error de análisis y, si tiene éxito, devolver el valor duplicado incluido en Ok.

Cargando editor...
Mostrar pista

Utilice `val.parse::<i32>()?` para convertir la cadena propagando el error, luego devuelva `Ok(num * 2)`.

Solución disponible después de 3 intentos

Ejercicio 3: Definir un error personalizado

Ejercicio#rust.m7.l2.e3
Intentos: 0Cargando...

Defina una estructura vacía llamada CustomError. Implemente el rasgo std::fmt::Display escribiendo el mensaje 'Se produjo un error personalizado' dentro del método fmt.

Cargando editor...
Mostrar pista

Declare `struct CustomError;`e implemente Display escribiendo`write!(f, "Si e verificato un errore personalizzato")`en el método `fmt`.

Solución disponible después de 3 intentos