En Rust, el manejo de errores es una parte fundamental del lenguaje, diseñada para ayudar a los desarrolladores a escribir código robusto y seguro. Uno de los mecanismos principales para manejar errores es el tipo Result. En esta sección, aprenderemos qué es Result, cómo usarlo y cómo manejar errores de manera efectiva.

¿Qué es Result?

El tipo Result es una enumeración (enum) que se utiliza para representar el resultado de una operación que puede fallar. Tiene dos variantes:

  • Ok(T): Indica que la operación fue exitosa y contiene un valor de tipo T.
  • Err(E): Indica que la operación falló y contiene un valor de tipo E, que describe el error.

La definición de Result se ve así:

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

Uso Básico de Result

Veamos un ejemplo simple de cómo usar Result en una función que intenta dividir dos números:

fn divide(dividend: f64, divisor: f64) -> Result<f64, String> {
    if divisor == 0.0 {
        Err(String::from("División por cero"))
    } else {
        Ok(dividend / divisor)
    }
}

fn main() {
    let result = divide(10.0, 2.0);
    match result {
        Ok(value) => println!("Resultado: {}", value),
        Err(e) => println!("Error: {}", e),
    }
}

Explicación del Código

  1. Definición de la Función divide:

    • La función divide toma dos parámetros dividend y divisor de tipo f64.
    • Retorna un Result<f64, String>, donde f64 es el tipo del valor exitoso y String es el tipo del error.
  2. Manejo del Error:

    • Si el divisor es 0.0, la función retorna Err con un mensaje de error.
    • Si no, retorna Ok con el resultado de la división.
  3. Uso de match para Manejar el Resultado:

    • En main, se llama a divide y se usa un match para manejar las variantes Ok y Err.

Métodos Comunes de Result

Rust proporciona varios métodos útiles para trabajar con Result. Aquí hay algunos de los más comunes:

unwrap

El método unwrap extrae el valor contenido en Ok o hace que el programa entre en pánico si es Err.

fn main() {
    let result = divide(10.0, 2.0);
    let value = result.unwrap();
    println!("Resultado: {}", value);
}

unwrap_or

El método unwrap_or proporciona un valor predeterminado en caso de error.

fn main() {
    let result = divide(10.0, 0.0);
    let value = result.unwrap_or(0.0);
    println!("Resultado: {}", value);
}

unwrap_or_else

El método unwrap_or_else ejecuta una función en caso de error.

fn main() {
    let result = divide(10.0, 0.0);
    let value = result.unwrap_or_else(|e| {
        println!("Error: {}", e);
        0.0
    });
    println!("Resultado: {}", value);
}

Ejercicio Práctico

Ejercicio

Escribe una función llamada read_file que intente leer el contenido de un archivo y retorne un Result<String, std::io::Error>. Usa esta función en main y maneja el resultado adecuadamente.

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

fn read_file(filename: &str) -> Result<String, io::Error> {
    let mut file = File::open(filename)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    Ok(contents)
}

fn main() {
    match read_file("example.txt") {
        Ok(contents) => println!("Contenido del archivo:\n{}", contents),
        Err(e) => println!("Error al leer el archivo: {}", e),
    }
}

Solución Explicada

  1. Importación de Módulos:

    • std::fs::File para manejar archivos.
    • std::io::{self, Read} para manejar errores de E/S y leer archivos.
  2. Definición de la Función read_file:

    • Toma un filename de tipo &str.
    • Intenta abrir el archivo con File::open. El operador ? propaga el error si ocurre.
    • Lee el contenido del archivo en una String usando file.read_to_string. Nuevamente, el operador ? propaga el error.
    • Retorna el contenido del archivo envuelto en Ok.
  3. Manejo del Resultado en main:

    • Usa un match para manejar las variantes Ok y Err.

Conclusión

El tipo Result es una herramienta poderosa en Rust para manejar errores de manera segura y explícita. Al usar Result, puedes escribir código que maneje fallos de manera predecible y robusta. En la siguiente sección, exploraremos otro tipo importante para el manejo de errores: Option.

© Copyright 2024. Todos los derechos reservados