Menu
Coddy logo textTech

Enums avec données

Fait partie de la section Programmation Orientée Objet du Journey Rust de Coddy. Leçon 14 sur 61.

Les énumérations de base en Rust vous permettent de définir un type avec un ensemble fixe de variantes, comme Direction::North ou Status::Active. Mais les énumérations Rust sont bien plus puissantes que cela. Chaque variante peut contenir ses propres données, ce qui rend les énumérations incroyablement flexibles pour modéliser des situations du monde réel.

Considérez un système de messagerie où différents types de messages transportent des informations différentes. Un message texte contient du contenu, une commande de déplacement contient des coordonnées et un signal de fin ne contient absolument rien. En Rust, vous pouvez représenter tous ces éléments avec une seule énumération :

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(u8, u8, u8),
}

Chaque variante a une forme différente. Quit ne contient aucune donnée : c'est simplement un signal.

Move utilise une syntaxe semblable à celle des structures avec des champs nommés. Write contient une seule String en utilisant une syntaxe de tuple. ChangeColor contient trois valeurs représentant les composantes RVB.

La création d’instances de ces variantes se présente comme suit :

let m1 = Message::Quit;
let m2 = Message::Move { x: 10, y: 20 };
let m3 = Message::Write(String::from("Hello"));
let m4 = Message::ChangeColor(255, 128, 0);

La beauté de cette approche est que m1, m2, m3 et m4 sont tous du même type : Message. Tu peux les stocker dans la même collection, les transmettre à la même fonction ou renvoyer n’importe quelle variante depuis une seule fonction. L’énumération unifie différentes structures de données sous un même type tout en préservant les informations spécifiques dont chaque variante a besoin.

challenge icon

Défi

Facile

Construisons un système de notifications qui utilise des énumérations avec des données pour représenter différents types d’alertes. Chaque type de notification contient des informations différentes : certaines ont des messages, certaines ont des valeurs numériques et certaines sont de simples signaux.

Vous allez créer deux fichiers pour organiser votre code :

  • notification.rs : définissez une énumération publique Notification avec trois variantes :
    • Alert : contient un unique message String (syntaxe de tuple)
    • Reminder : contient des champs nommés : title (String) et minutes (u32)
    • Dismiss : ne contient aucune donnée, c’est simplement un signal
  • main.rs : ajoutez votre module de notifications et créez une instance de chaque variante. Affichez ensuite des informations sur chaque notification pour démontrer que les trois variantes sont du même type, tout en contenant des données différentes.

Lors de l’affichage, utilisez le formatage de débogage ({:?}) pour afficher chaque notification. Vous devrez dériver le trait Debug sur votre énumération afin de pouvoir l’afficher de cette manière.

Votre sortie doit afficher les trois notifications, chacune sur sa propre ligne :

Alert("{message}")
Reminder { title: "{title}", minutes: {minutes} }
Dismiss

Par exemple, avec un message d’alerte "Server down", un rappel dont le titre est "Meeting" et une durée de 30 minutes, la sortie serait :

Alert("Server down")
Reminder { title: "Meeting", minutes: 30 }
Dismiss

Vous recevrez trois entrées : le message d’alerte, le titre du rappel et le nombre de minutes du rappel.

Essayez vous-même

mod notification;

use notification::Notification;

fn main() {
    // Lire les entrées
    let mut alert_message = String::new();
    std::io::stdin().read_line(&mut alert_message).expect("Failed to read line");
    let alert_message = alert_message.trim().to_string();

    let mut reminder_title = String::new();
    std::io::stdin().read_line(&mut reminder_title).expect("Failed to read line");
    let reminder_title = reminder_title.trim().to_string();

    let mut minutes_input = String::new();
    std::io::stdin().read_line(&mut minutes_input).expect("Failed to read line");
    let reminder_minutes: u32 = minutes_input.trim().parse().expect("Failed to parse minutes");

    // TODO: Créer une notification Alert en utilisant alert_message

    // TODO: Create a Reminder notification using reminder_title and reminder_minutes

    // TODO: Créer une notification Dismiss

    // TODO: Afficher chaque notification en utilisant le formatage de débogage {:?}
    // Chaque notification doit être affichée sur sa propre ligne
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur Rust en ligne