Manejo de errores en Rust con el signo de interrogación

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, aprenderemos sobre el operador ? en Rust, que nos permite simplificar el manejo de errores devolviendo Err en lugar de causar un panic, y también exploraremos la macro try!, que lograba una funcionalidad similar antes de que se introdujera ?.

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/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/ErrorHandlingandDebuggingGroup(["Error Handling and Debugging"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/integer_types("Integer Types") rust/DataTypesGroup -.-> rust/string_type("String Type") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/ErrorHandlingandDebuggingGroup -.-> rust/error_propagation("Error Propagation") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99243{{"Manejo de errores en Rust con el signo de interrogación"}} rust/integer_types -.-> lab-99243{{"Manejo de errores en Rust con el signo de interrogación"}} rust/string_type -.-> lab-99243{{"Manejo de errores en Rust con el signo de interrogación"}} rust/function_syntax -.-> lab-99243{{"Manejo de errores en Rust con el signo de interrogación"}} rust/expressions_statements -.-> lab-99243{{"Manejo de errores en Rust con el signo de interrogación"}} rust/error_propagation -.-> lab-99243{{"Manejo de errores en Rust con el signo de interrogación"}} rust/operator_overloading -.-> lab-99243{{"Manejo de errores en Rust con el signo de interrogación"}} end

Presentando ?

A veces solo queremos la simplicidad de unwrap sin la posibilidad de un panic. Hasta ahora, unwrap nos ha obligado a anidar cada vez más profundamente cuando lo que realmente queríamos era obtener la variable fuera. Esto es exactamente el propósito de ?.

Al encontrar un Err, hay dos acciones válidas que se pueden tomar:

  1. panic! que ya decidimos tratar de evitar si es posible
  2. return porque un Err significa que no se puede manejar

? es casi[^†] exactamente equivalente a un unwrap que returns en lugar de panicar en Errs. Veamos cómo podemos simplificar el ejemplo anterior que usaba combinadores:

use std::num::ParseIntError;

fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    let first_number = first_number_str.parse::<i32>()?;
    let second_number = second_number_str.parse::<i32>()?;

    Ok(first_number * second_number)
}

fn print(result: Result<i32, ParseIntError>) {
    match result {
        Ok(n)  => println!("n es {}", n),
        Err(e) => println!("Error: {}", e),
    }
}

fn main() {
    print(multiply("10", "2"));
    print(multiply("t", "2"));
}

La macro try!

Antes de que existiera ?, la misma funcionalidad se lograba con la macro try!. Ahora se recomienda el operador ?, pero es posible que aún encuentres try! al revisar código antiguo. La misma función multiply del ejemplo anterior se vería así usando try!:

// Para compilar y ejecutar este ejemplo sin errores, mientras se usa Cargo, cambia el valor
// del campo `edition`, en la sección `[package]` del archivo `Cargo.toml`, a "2015".

use std::num::ParseIntError;

fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    let first_number = try!(first_number_str.parse::<i32>());
    let second_number = try!(second_number_str.parse::<i32>());

    Ok(first_number * second_number)
}

fn print(result: Result<i32, ParseIntError>) {
    match result {
        Ok(n)  => println!("n es {}", n),
        Err(e) => println!("Error: {}", e),
    }
}

fn main() {
    print(multiply("10", "2"));
    print(multiply("t", "2"));
}

Resumen

¡Felicidades! Has completado el laboratorio Presentando ?. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.