Map pour Result

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, nous explorons comment utiliser des combinateurs tels que map et and_then pour le type Result en Rust pour gérer les erreurs de manière plus élégante, comme le montrent les exemples fournis.

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/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) 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/DataTypesGroup -.-> rust/type_casting("Type Conversion and Casting") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99240{{"Map pour Result"}} rust/integer_types -.-> lab-99240{{"Map pour Result"}} rust/string_type -.-> lab-99240{{"Map pour Result"}} rust/type_casting -.-> lab-99240{{"Map pour Result"}} rust/function_syntax -.-> lab-99240{{"Map pour Result"}} rust/expressions_statements -.-> lab-99240{{"Map pour Result"}} rust/operator_overloading -.-> lab-99240{{"Map pour Result"}} end

map pour Result

Générer une panique dans la fonction multiply de l'exemple précédent ne conduit pas à un code robuste. Généralement, nous souhaitons renvoyer l'erreur à l'appelant afin qu'il puisse décider de la manière appropriée de répondre aux erreurs.

Nous devons tout d'abord savoir quel type d'erreur nous sommes en train de gérer. Pour déterminer le type Err, nous regardons parse(), qui est implémenté avec le trait FromStr pour i32. Par conséquent, le type Err est spécifié comme étant ParseIntError.

Dans l'exemple ci-dessous, l'utilisation directe d'une instruction match conduit à un code globalement plus lourd.

use std::num::ParseIntError;

// En réécrivant le type de retour, nous utilisons la correspondance de motifs sans `unwrap()`.
fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    match first_number_str.parse::<i32>() {
        Ok(first_number)  => {
            match second_number_str.parse::<i32>() {
                Ok(second_number)  => {
                    Ok(first_number * second_number)
                },
                Err(e) => Err(e),
            }
        },
        Err(e) => Err(e),
    }
}

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

fn main() {
    // Cela fournit toujours une réponse raisonnable.
    let twenty = multiply("10", "2");
    print(twenty);

    // Celui-ci fournit maintenant un message d'erreur beaucoup plus utile.
    let tt = multiply("t", "2");
    print(tt);
}

Heureusement, les fonctions map, and_then de Option et de nombreux autres combinateurs sont également implémentés pour Result. Result contient une liste complète.

use std::num::ParseIntError;

// Comme pour `Option`, nous pouvons utiliser des combinateurs tels que `map()`.
// Cette fonction est sinon identique à la précédente et peut être lue comme suit :
// Multipliez si les deux valeurs peuvent être analysées à partir de str, sinon propagez l'erreur.
fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    first_number_str.parse::<i32>().and_then(|first_number| {
        second_number_str.parse::<i32>().map(|second_number| first_number * second_number)
    })
}

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

fn main() {
    // Cela fournit toujours une réponse raisonnable.
    let twenty = multiply("10", "2");
    print(twenty);

    // Celui-ci fournit maintenant un message d'erreur beaucoup plus utile.
    let tt = multiply("t", "2");
    print(tt);
}

Résumé

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