Menu
Coddy logo textTech

Traits avec paramètres

Fait partie de la section Object Oriented Programming du Journey Rust de Coddy — leçon 33 sur 61.

Jusqu'à présent, nos méthodes de trait n'ont pris que &self comme paramètre. Mais les méthodes de trait peuvent accepter des paramètres supplémentaires tout comme les méthodes régulières — cela les rend bien plus utiles pour les opérations du monde réel.

Lors de la définition d'un trait, vous pouvez inclure tous les paramètres dont vous avez besoin dans les signatures de méthode :

trait Calculator {
    fn add(&self, a: i32, b: i32) -> i32;
    fn multiply(&self, a: i32, b: i32) -> i32;
}

Ce trait Calculator nécessite 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
    }
}

Maintenant, vous pouvez 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 — peut-être qu'un LoggingCalc pourrait afficher chaque opération avant de renvoyer le résultat.

challenge icon

Défi

Facile

Construisons une boîte à outils de manipulation de chaînes de caractères où différents processeurs peuvent transformer du 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 organiserez votre code sur trois fichiers :

  • processor.rs : Définissez un trait public TextProcessor avec deux méthodes qui acceptent des paramètres :
    • repeat(&self, text: &str, times: u32) -> String — répète le texte donné un nombre spécifié de fois
    • truncate(&self, text: &str, max_len: usize) -> String — raccourcit le texte à 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 tronque en coupant simplement à la longueur maximale
    • FancyProcessor — 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 tronque en ajoutant "..." si le texte a été raccourci (uniquement si le texte original était plus long que max_len)
  • main.rs : Rassemblez vos modules et démontrez comment les mêmes méthodes de 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 remplissent le même contrat TextProcessor, mais chacun transforme le texte à sa manière unique. 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 comme u32), et la longueur maximale pour la troncature (à analyser comme usize).

Aide-mémoire

Les méthodes de trait peuvent accepter des paramètres supplémentaires au-delà de &self :

trait Calculator {
    fn add(&self, a: i32, b: i32) -> i32;
    fn multiply(&self, a: i32, b: i32) -> i32;
}

Implémentation d'un trait avec des paramètres :

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
    }
}

Utilisation des méthodes de trait 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.

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}
}
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 Object Oriented Programming