Méthodes sur les Enums
Fait partie de la section Object Oriented Programming 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'attacher un comportement directement à votre type d'énumération, facilitant ainsi le travail avec différentes variantes via 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 de la même manière que pour les structures. La méthode prend &self pour accéder à l'instance de l'énumération. À l'intérieur de la méthode, vous utilisez match pour déterminer à quelle variante vous avez affaire et renvoyer le résultat approprié.
L'appel de la méthode est identique quelle que soit la variante que vous possédez :
fn main() {
let m1 = Message::Quit;
let m2 = Message::Move { x: 10, y: 20 };
println!("{}", m1.describe()); // Signal d'arrêt
println!("{}", m2.describe()); // Déplacement 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'enum gère le reste en interne. Le comportement change en fonction de la variante, mais l'interface reste cohérente.
Défi
FacileConstruisons un système de feux de signalisation qui utilise une énumération avec des méthodes pour décrire l'état actuel du signal. Chaque couleur de feu portera des informations sur sa durée, et une méthode fournira une description lisible par l'homme.
Vous allez créer deux fichiers pour organiser votre code :
traffic.rs: Définissez une énumération publiqueTrafficLightavec trois variantes :Red— contient unu32représentant les secondes d'attenteYellow— contient unu32représentant les secondes d'attenteGreen— contient unu32représentant les secondes pour passer
statusqui retourne uneStringdécrivant le feu. Utilisezmatchà l'intérieur de la méthode pour gérer chaque variante et inclure la durée dans le message.main.rs: Importez votre module traffic, créez des instances de chaque variante de feu, et appelez la méthodestatussur chacune pour afficher les descriptions.
La méthode status doit retourner des messages dans ces formats exacts :
- Pour
Red:Stop for {seconds} seconds - Pour
Yellow:Caution for {seconds} seconds - Pour
Green:Go for {seconds} seconds
Votre sortie doit afficher le statut 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 jaune de 5 secondes et un vert de 25 secondes, la sortie serait :
Stop for 30 seconds
Caution for 5 seconds
Go for 25 secondsVous recevrez trois entrées : la durée du feu rouge, la durée du feu jaune et la durée du feu vert.
Aide-mémoire
Les enums peuvent avoir des méthodes définies dans des blocs impl, tout comme les structs :
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),
}
}
}
Les méthodes prennent &self pour accéder à l'instance de l'enum et utilisent match pour gérer les différentes variantes :
let m1 = Message::Quit;
let m2 = Message::Move { x: 10, y: 20 };
println!("{}", m1.describe()); // Signal de sortie
println!("{}", m2.describe()); // Déplacement vers (10, 20)
L'appelant utilise la même interface quelle que soit la variante — l'enum gère le comportement en interne selon la variante dont il s'agit.
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 saisies
// 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 Object Oriented Programming
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édia