Simplifier la gestion des types Option en Rust avec Map

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 l'utilisation du combinateur map() en Rust pour simplifier le flux de contrôle et gérer les types Option de manière concise et modulaire.

Note : Si le nom de fichier n'est pas spécifié dans le laboratoire, 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/MemorySafetyandManagementGroup(["Memory Safety and Management"]) 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/FunctionsandClosuresGroup(["Functions and Closures"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") 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/error_propagation("Error Propagation") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99236{{"Simplifier la gestion des types Option en Rust avec Map"}} rust/function_syntax -.-> lab-99236{{"Simplifier la gestion des types Option en Rust avec Map"}} rust/expressions_statements -.-> lab-99236{{"Simplifier la gestion des types Option en Rust avec Map"}} rust/lifetime_specifiers -.-> lab-99236{{"Simplifier la gestion des types Option en Rust avec Map"}} rust/method_syntax -.-> lab-99236{{"Simplifier la gestion des types Option en Rust avec Map"}} rust/error_propagation -.-> lab-99236{{"Simplifier la gestion des types Option en Rust avec Map"}} rust/operator_overloading -.-> lab-99236{{"Simplifier la gestion des types Option en Rust avec Map"}} end

Combinateurs : map

match est une méthode valide pour gérer les Option. Cependant, vous finirez peut-être par trouver qu'un usage intensif est fastidieux, en particulier avec des opérations valides uniquement pour une entrée. Dans ces cas, les combinateurs peuvent être utilisés pour gérer le flux de contrôle de manière modulaire.

Option a une méthode intégrée appelée map(), un combinateur pour la simple transformation de Some -> Some et None -> None. Plusieurs appels de map() peuvent être chaînés ensemble pour une plus grande flexibilité.

Dans l'exemple suivant, process() remplace toutes les fonctions précédentes tout en restant compact.

#![allow(dead_code)]

#[derive(Debug)] enum Food { Apple, Carrot, Potato }

#[derive(Debug)] struct Peeled(Food);
#[derive(Debug)] struct Chopped(Food);
#[derive(Debug)] struct Cooked(Food);

// Épluchez les aliments. S'il n'y en a pas, renvoyez `None`.
// Sinon, renvoyez l'aliment épluché.
fn peel(food: Option<Food>) -> Option<Peeled> {
    match food {
        Some(food) => Some(Peeled(food)),
        None       => None,
    }
}

// Coupez les aliments. S'il n'y en a pas, renvoyez `None`.
// Sinon, renvoyez l'aliment coupé.
fn chop(peeled: Option<Peeled>) -> Option<Chopped> {
    match peeled {
        Some(Peeled(food)) => Some(Chopped(food)),
        None               => None,
    }
}

// Cuisez les aliments. Ici, nous présentons `map()` au lieu de `match` pour la gestion des cas.
fn cook(chopped: Option<Chopped>) -> Option<Cooked> {
    chopped.map(|Chopped(food)| Cooked(food))
}

// Une fonction pour éplucher, couper et cuire les aliments dans cet ordre.
// Nous chainons plusieurs utilisations de `map()` pour simplifier le code.
fn process(food: Option<Food>) -> Option<Cooked> {
    food.map(|f| Peeled(f))
     .map(|Peeled(f)| Chopped(f))
     .map(|Chopped(f)| Cooked(f))
}

// Vérifiez s'il y a des aliments ou non avant d'essayer de les manger!
fn eat(food: Option<Cooked>) {
    match food {
        Some(food) => println!("Mmm. I love {:?}", food),
        None       => println!("Oh no! It wasn't edible."),
    }
}

fn main() {
    let apple = Some(Food::Apple);
    let carrot = Some(Food::Carrot);
    let potato = None;

    let cooked_apple = cook(chop(peel(apple)));
    let cooked_carrot = cook(chop(peel(carrot)));
    // Essayons maintenant la plus simple `process()`.
    let cooked_potato = process(potato);

    eat(cooked_apple);
    eat(cooked_carrot);
    eat(cooked_potato);
}

Sommaire

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