Méthodes sur les Enums
Fait partie de la section Programmation Orientée Objet du Journey Rust de Coddy. Leçon 15 sur 61.
Tout comme les structures, les énumérations peuvent avoir des méthodes définies dans des blocs impl. Cela vous permet d’associer directement un comportement à votre type d’énumération, ce qui facilite l’utilisation de différentes variantes au moyen d’une interface unifiée.
Voici comment ajouter une méthode à l’énumération Message de la leçon précédente :
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
}
impl Message {
fn describe(&self) -> String {
match self {
Message::Quit => String::from("Quit signal"),
Message::Move { x, y } => format!("Move to ({}, {})", x, y),
Message::Write(text) => format!("Message: {}", text),
}
}
}
Le bloc impl Message fonctionne exactement comme pour les structures. La méthode prend &self pour accéder à l’instance de l’énumération. Dans la méthode, vous utilisez match pour déterminer avec quelle variante vous travaillez et renvoyer le résultat approprié.
Appeler la méthode se présente de la même manière, quelle que soit la variante que vous avez :
fn main() {
let m1 = Message::Quit;
let m2 = Message::Move { x: 10, y: 20 };
println!("{}", m1.describe()); // Signal de quitter
println!("{}", m2.describe()); // Déplacer vers (10, 20)
}
Ce modèle est puissant, car l’appelant n’a pas besoin de savoir quelle variante il possède. Il appelle simplement la méthode, et l’énumération gère le reste en interne. Le comportement change selon la variante, mais l’interface reste cohérente.
Défi
FacileConstruisons un système de feux de circulation qui utilise une énumération avec des méthodes pour décrire l’état actuel du signal. Chaque couleur de feu contiendra des informations sur sa durée, et une méthode fournira une description compréhensible par l’utilisateur.
Tu créeras deux fichiers pour organiser ton code :
traffic.rs: définis une énumération publiqueTrafficLightavec trois variantes :Red: contient unu32représentant le nombre de secondes d’attenteYellow: contient unu32représentant le nombre de secondes d’attenteGreen: contient unu32représentant le nombre de secondes avant de pouvoir avancer
statusqui renvoie uneStringdécrivant le feu. Utilisematchdans la méthode pour gérer chaque variante et inclure la durée dans le message.main.rs: importe ton module de gestion des feux, crée des instances de chaque variante de feu et appelle la méthodestatussur chacune pour afficher les descriptions.
La méthode status doit renvoyer des messages dans ces formats exacts :
- Pour
Red:Stop for {seconds} seconds - Pour
Yellow:Caution for {seconds} seconds - Pour
Green:Go for {seconds} seconds
Ta sortie doit afficher l’état de chaque feu sur sa propre ligne :
Stop for {seconds} seconds
Caution for {seconds} seconds
Go for {seconds} secondsPar exemple, avec un feu rouge de 30 secondes, un feu jaune de 5 secondes et un feu vert de 25 secondes, la sortie serait :
Stop for 30 seconds
Caution for 5 seconds
Go for 25 secondsTu recevras trois entrées : la durée du feu rouge, la durée du feu jaune et la durée du feu vert.
Essayez vous-même
mod traffic;
use traffic::TrafficLight;
fn main() {
// Lire les entrées pour les durées
let mut red_input = String::new();
std::io::stdin().read_line(&mut red_input).expect("Failed to read line");
let red_duration: u32 = red_input.trim().parse().expect("Invalid number");
let mut yellow_input = String::new();
std::io::stdin().read_line(&mut yellow_input).expect("Failed to read line");
let yellow_duration: u32 = yellow_input.trim().parse().expect("Invalid number");
let mut green_input = String::new();
std::io::stdin().read_line(&mut green_input).expect("Failed to read line");
let green_duration: u32 = green_input.trim().parse().expect("Invalid number");
// TODO: Créer des instances de chaque variante de TrafficLight avec les durées d'entrée
// TODO: Appeler la méthode status sur chaque feu et afficher le résultat
}
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
1Méthodes et comportement
Introduction aux blocs d'implémentationLe paramètre SelfMéthodes mutablesFonctions associéesBlocs d'implémentation multiplesChaînage de méthodesRécapitulatif - Actions sur le rectangle4Projet : Animal virtuel
Définir l'animalNourrir l'animal7Traits standards
Le trait DebugLe trait DisplayClone et CopyLes traits d'égalitéRécapitulatif - Point affichable10Projet : Système de documents
Le trait DrawComposant texte2Encapsulation et modules
Bases des modulesLe mot-clé publicChamps privésGettersSettersRécapitulatif - Casier sécurisé5Généricité
Structures génériquesMéthodes génériquesPlusieurs types génériquesFonctions génériquesRécapitulatif - Point de coordonnées8Les Traits comme contraintes
Syntaxe des contraintes de traitContraintes multiplesLa clause whereRetourner des types avec des traitsRécapitulatif - Afficheur générique11Design Patterns en Rust
Le pattern NewtypeCompositionLe trait DropFrom et IntoRécapitulatif - Mock de Smart Pointer3Enums avancées
Enums avec donnéesMéthodes sur les EnumsMatching des variantes de donnéesL'Enum Option revisitéeRécapitulatif - Enum Shape6Définition des Traits
Qu'est-ce qu'un Trait ?Implémenter des TraitsImplémentations par défautRedéfinir les comportements par défautTraits avec paramètresRécapitulatif - Lecteur multimédiaEntraînez-vous par vous-même : Compilateur Rust en ligne