Traits avec paramètres
Fait partie de la section Programmation Orientée Objet du Journey Rust de Coddy. Leçon 33 sur 61.
Jusqu’à présent, nos méthodes de trait n’ont accepté que &self comme paramètre. Mais les méthodes de trait peuvent accepter des paramètres supplémentaires, tout comme les méthodes ordinaires. Cela les rend bien plus utiles pour les opérations du monde réel.
Lorsque vous définissez un trait, vous pouvez inclure tous les paramètres dont vous avez besoin dans les signatures des méthodes :
trait Calculator {
fn add(&self, a: i32, b: i32) -> i32;
fn multiply(&self, a: i32, b: i32) -> i32;
}
Ce trait Calculator exige deux méthodes, chacune acceptant deux entiers en plus de &self. Tout type implémentant ce trait doit fournir les deux opérations avec ces signatures exactes.
Voici comment une structure pourrait l’implémenter :
struct BasicCalc;
impl Calculator for BasicCalc {
fn add(&self, a: i32, b: i32) -> i32 {
a + b
}
fn multiply(&self, a: i32, b: i32) -> i32 {
a * b
}
}
Vous pouvez maintenant utiliser ces méthodes avec des arguments :
let calc = BasicCalc;
println!("{}", calc.add(5, 3)); // 8
println!("{}", calc.multiply(4, 7)); // 28
Le trait définit quels paramètres chaque méthode accepte, tandis que l’implémentation définit comment ces paramètres sont utilisés. Cela permet à différents types d’effectuer les mêmes opérations à leur manière : par exemple, un LoggingCalc pourrait afficher chaque opération avant de renvoyer le résultat.
Défi
FacileConstruisons une boîte à outils de manipulation de chaînes dans laquelle différents processeurs peuvent transformer le texte à leur manière ! Vous allez créer un trait TextProcessor avec des méthodes qui acceptent des paramètres, puis l'implémenter pour deux types de processeurs différents.
Vous allez organiser votre code sur trois fichiers :
processor.rs: définissez un trait publicTextProcessoravec deux méthodes qui acceptent des paramètres :repeat(&self, text: &str, times: u32) -> String: répète le texte donné un nombre de fois spécifiétruncate(&self, text: &str, max_len: usize) -> String: raccourcit le texte jusqu'à la longueur maximale spécifiée
processors.rs: créez deux structures publiques qui implémentent votre trait :SimpleProcessor: une structure unitaire qui répète le texte avec des espaces entre chaque répétition (par exemple, « Hi » répété 3 fois devient « Hi Hi Hi ») et le tronque en le coupant simplement à la longueur maximaleFancyProcessor: une structure unitaire qui répète le texte avec « * » entre les répétitions (par exemple, « Hi » répété 3 fois devient « Hi * Hi * Hi ») et le tronque en ajoutant « ... » si le texte a été raccourci (uniquement si le texte d'origine était plus long que max_len)
main.rs: réunissez vos modules et montrez comment les mêmes méthodes du trait produisent des résultats différents selon le processeur que vous utilisez.
Dans votre fichier principal, créez les deux processeurs et utilisez les entrées pour les tester. Vous recevrez trois entrées : une chaîne de texte, un nombre de répétitions et une longueur maximale.
Affichez quatre lignes montrant le comportement de chaque processeur :
Simple repeat: {result}
Simple truncate: {result}
Fancy repeat: {result}
Fancy truncate: {result}Par exemple, avec les entrées Hello, 3 et 4 :
Simple repeat: Hello Hello Hello
Simple truncate: Hell
Fancy repeat: Hello * Hello * Hello
Fancy truncate: Hell...Remarquez comment les deux processeurs respectent le même contrat TextProcessor, mais que chacun transforme le texte à sa manière ! Le trait définit quels paramètres les méthodes acceptent, tandis que chaque implémentation décide comment les utiliser !
Vous recevrez trois entrées : le texte à traiter, le nombre de répétitions (à analyser en tant que u32) et la longueur maximale pour la troncature (à analyser en tant que usize).
Essayez vous-même
mod processor;
mod processors;
use processor::TextProcessor;
use processors::{SimpleProcessor, FancyProcessor};
fn main() {
// Lire les entrées
let mut text = String::new();
std::io::stdin().read_line(&mut text).expect("Failed to read line");
let text = text.trim();
let mut times_input = String::new();
std::io::stdin().read_line(&mut times_input).expect("Failed to read line");
let times: u32 = times_input.trim().parse().expect("Failed to parse times");
let mut max_len_input = String::new();
std::io::stdin().read_line(&mut max_len_input).expect("Failed to read line");
let max_len: usize = max_len_input.trim().parse().expect("Failed to parse max_len");
// Créer les processeurs
let simple = SimpleProcessor;
let fancy = FancyProcessor;
// TODO: Utiliser les processeurs pour transformer le texte et afficher les résultats
// Afficher quatre lignes :
// Simple repeat: {result}
// Simple truncate: {result}
// Fancy repeat: {result}
// Fancy truncate: {result}
}
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