Implémenter des Traits
Fait partie de la section Programmation Orientée Objet du Journey Rust de Coddy. Leçon 30 sur 61.
Maintenant que tu sais comment définir un trait, voyons comment faire en sorte qu’une structure respecte ce contrat. L’implémentation d’un trait relie l’exigence abstraite à un comportement concret.
La syntaxe utilise impl TraitName for StructName :
trait Speak {
fn speak(&self) -> String;
}
struct Dog {
name: String,
}
impl Speak for Dog {
fn speak(&self) -> String {
format!("{} says: Woof!", self.name)
}
}
Le bloc impl Speak for Dog indique à Rust que Dog implémente le trait Speak. À l’intérieur, vous fournissez le corps réel de la méthode. C’est ici que vous définissez comment un chien s’exprime.
La puissance des traits devient évidente lorsque plusieurs types implémentent le même trait :
struct Cat {
name: String,
}
impl Speak for Cat {
fn speak(&self) -> String {
format!("{} says: Meow!", self.name)
}
}
Dog et Cat partagent désormais la capacité Speak, mais chacun fournit sa propre implémentation unique. Vous pouvez appeler .speak() sur l’un ou l’autre type :
let dog = Dog { name: String::from("Rex") };
let cat = Cat { name: String::from("Whiskers") };
println!("{}", dog.speak()); // Rex dit : Ouaf !
println!("{}", cat.speak()); // Whiskers dit : Miaou !
C’est le fondement du polymorphisme en Rust : des types différents, une même interface, des comportements uniques.
Défi
FacileDonnons vie aux traits en les implémentant pour différents types ! Vous allez créer un trait Describable et l’implémenter pour deux structures différentes, chacune fournissant sa propre description unique.
Vous organiserez votre code dans trois fichiers :
describable.rs: définissez un trait publicDescribableavec une méthodedescribe(&self) -> String.items.rs: créez deux structures publiques qui implémentent votre trait :Bookavec un champ publictitle(String)Movieavec un champ publicname(String)
Describableavec son propre format de description unique.main.rs: réunissez vos modules, créez des instances des deux structures et appelez leurs méthodesdescribepour montrer comment le même trait produit des résultats différents pour différents types.
Votre Book doit se décrire comme Book: {title} et votre Movie doit se décrire comme Film: {name}. Remarquez comment chaque type respecte le même contrat, tout en ayant son propre comportement !
Dans votre fichier principal, créez un livre et un film à l’aide des deux entrées fournies, puis affichez leurs descriptions sur des lignes séparées.
Votre sortie doit respecter ce format :
Book: {title}
Film: {name}Par exemple, avec les entrées 1984 et Inception :
Book: 1984
Film: InceptionVous recevrez deux entrées : le titre d’un livre et le nom d’un film.
REQUIRED OUTPUT FORMAT:Essayez vous-même
mod describable;
mod items;
use describable::Describable;
use items::{Book, Movie};
fn main() {
// Lire les entrées
let mut title = String::new();
std::io::stdin().read_line(&mut title).expect("Failed to read line");
let title = title.trim().to_string();
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Failed to read line");
let name = name.trim().to_string();
// TODO: Créer une instance de Book avec le title
// TODO: Créer une instance de Movie avec le name
// TODO: Afficher la description du book
// TODO: Afficher la description du movie
}
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