Explorando el enum Result de Rust

RustRustBeginner
Practicar Ahora

This tutorial is from open-source community. Access the source code

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, exploramos el enum Result en Rust, que nos permite expresar el éxito o el fracaso de una operación devolviendo ya sea Ok con un valor o Err con una explicación del fracaso.

Nota: Si el laboratorio no especifica un nombre de archivo, puede usar cualquier nombre de archivo que desee. Por ejemplo, puede usar main.rs, compilar y ejecutarlo con rustc main.rs &&./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/DataStructuresandEnumsGroup(["Data Structures and Enums"]) rust(("Rust")) -.-> rust/ErrorHandlingandDebuggingGroup(["Error Handling and Debugging"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/MemorySafetyandManagementGroup(["Memory Safety and Management"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/floating_types("Floating-point Types") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("Lifetime Specifiers") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("Method Syntax") rust/ErrorHandlingandDebuggingGroup -.-> rust/panic_usage("panic! Usage") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99257{{"Explorando el enum Result de Rust"}} rust/floating_types -.-> lab-99257{{"Explorando el enum Result de Rust"}} rust/function_syntax -.-> lab-99257{{"Explorando el enum Result de Rust"}} rust/expressions_statements -.-> lab-99257{{"Explorando el enum Result de Rust"}} rust/lifetime_specifiers -.-> lab-99257{{"Explorando el enum Result de Rust"}} rust/method_syntax -.-> lab-99257{{"Explorando el enum Result de Rust"}} rust/panic_usage -.-> lab-99257{{"Explorando el enum Result de Rust"}} rust/operator_overloading -.-> lab-99257{{"Explorando el enum Result de Rust"}} end

Result

Hemos visto que el enum Option se puede usar como valor de retorno de funciones que pueden fallar, donde se puede devolver None para indicar el fracaso. Sin embargo, a veces es importante expresar por qué una operación falló. Para hacer esto tenemos el enum Result.

El enum Result<T, E> tiene dos variantes:

  • Ok(value) que indica que la operación tuvo éxito y envuelve el value devuelto por la operación. (value tiene tipo T)
  • Err(why), que indica que la operación falló y envuelve why, que (esperemos) explica la causa del fracaso. (why tiene tipo E)
mod checked {
    // "Errores" matemáticos que queremos capturar
    #[derive(Debug)]
    pub enum MathError {
        DivisionByZero,
        NonPositiveLogarithm,
        NegativeSquareRoot,
    }

    pub type MathResult = Result<f64, MathError>;

    pub fn div(x: f64, y: f64) -> MathResult {
        if y == 0.0 {
            // Esta operación `fallaría`, en lugar de eso, devolvemos la razón del
            // fracaso envuelta en `Err`
            Err(MathError::DivisionByZero)
        } else {
            // Esta operación es válida, devolvemos el resultado envuelto en `Ok`
            Ok(x / y)
        }
    }

    pub fn sqrt(x: f64) -> MathResult {
        if x < 0.0 {
            Err(MathError::NegativeSquareRoot)
        } else {
            Ok(x.sqrt())
        }
    }

    pub fn ln(x: f64) -> MathResult {
        if x <= 0.0 {
            Err(MathError::NonPositiveLogarithm)
        } else {
            Ok(x.ln())
        }
    }
}

// `op(x, y)` === `sqrt(ln(x / y))`
fn op(x: f64, y: f64) -> f64 {
    // ¡Este es un triángulo de coincidencias de tres niveles!
    match checked::div(x, y) {
        Err(why) => panic!("{:?}", why),
        Ok(ratio) => match checked::ln(ratio) {
            Err(why) => panic!("{:?}", why),
            Ok(ln) => match checked::sqrt(ln) {
                Err(why) => panic!("{:?}", why),
                Ok(sqrt) => sqrt,
            },
        },
    }
}

fn main() {
    // ¿Esto fallará?
    println!("{}", op(1.0, 10.0));
}

Resumen

¡Felicitaciones! Has completado el laboratorio de Result. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.