L'opérateur Rust simplifie la gestion des erreurs

RustRustBeginner
Pratiquer maintenant

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

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire, l'opérateur ? est introduit comme un moyen de rendre le code plus propre lorsqu'on chaîne des résultats. Il est utilisé à la fin d'une expression renvoyant un Result et simplifie le code en gérant automatiquement les branches Err et Ok. L'exemple fourni montre comment utiliser l'opérateur ? en Rust pour gérer diverses opérations mathématiques et leurs éventuelles erreurs.

Note : Si le laboratoire ne spécifie pas de nom de fichier, vous pouvez utiliser n'importe quel nom de fichier que vous voulez. Par exemple, vous pouvez utiliser main.rs, le compiler et l'exécuter avec rustc main.rs &&./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL 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/DataStructuresandEnumsGroup(["Data Structures and Enums"]) rust(("Rust")) -.-> rust/ErrorHandlingandDebuggingGroup(["Error Handling and Debugging"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/floating_types("Floating-point Types") rust/DataTypesGroup -.-> rust/string_type("String Type") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") 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-150172{{"L'opérateur Rust simplifie la gestion des erreurs"}} rust/floating_types -.-> lab-150172{{"L'opérateur Rust simplifie la gestion des erreurs"}} rust/string_type -.-> lab-150172{{"L'opérateur Rust simplifie la gestion des erreurs"}} rust/function_syntax -.-> lab-150172{{"L'opérateur Rust simplifie la gestion des erreurs"}} rust/expressions_statements -.-> lab-150172{{"L'opérateur Rust simplifie la gestion des erreurs"}} rust/method_syntax -.-> lab-150172{{"L'opérateur Rust simplifie la gestion des erreurs"}} rust/panic_usage -.-> lab-150172{{"L'opérateur Rust simplifie la gestion des erreurs"}} rust/operator_overloading -.-> lab-150172{{"L'opérateur Rust simplifie la gestion des erreurs"}} end

?

La chaîne de résultats en utilisant match peut devenir assez difficile à lire ; heureusement, l'opérateur ? peut être utilisé pour remettre les choses dans l'ordre. ? est utilisé à la fin d'une expression renvoyant un Result, et est équivalent à une expression match, où la branche Err(err) se développe en un return Err(From::from(err)) précoce, et la branche Ok(ok) se développe en une expression ok.

mod checked {
    #[derive(Debug)]
    enum MathError {
        DivisionByZero,
        NonPositiveLogarithm,
        NegativeSquareRoot,
    }

    type MathResult = Result<f64, MathError>;

    fn div(x: f64, y: f64) -> MathResult {
        if y == 0.0 {
            Err(MathError::DivisionByZero)
        } else {
            Ok(x / y)
        }
    }

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

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

    // Fonction intermédiaire
    fn op_(x: f64, y: f64) -> MathResult {
        // si `div` "échoue", alors `DivisionByZero` sera `return`é
        let ratio = div(x, y)?;

        // si `ln` "échoue", alors `NonPositiveLogarithm` sera `return`é
        let ln = ln(ratio)?;

        sqrt(ln)
    }

    pub fn op(x: f64, y: f64) {
        match op_(x, y) {
            Err(why) => panic!("{}", match why {
                MathError::NonPositiveLogarithm
                    => "logarithme d'un nombre non positif",
                MathError::DivisionByZero
                    => "division par zéro",
                MathError::NegativeSquareRoot
                    => "racine carrée d'un nombre négatif",
            }),
            Ok(value) => println!("{}", value),
        }
    }
}

fn main() {
    checked::op(1.0, 10.0);
}

N'oubliez pas de consulter la documentation, car il existe de nombreuses méthodes pour mapper/composer Result.

Résumé

Félicitations ! Vous avez terminé le laboratoire ?. Vous pouvez pratiquer d'autres laboratoires sur LabEx pour améliorer vos compétences.