Menu
Coddy logo textTech

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.

challenge icon

Défi

Facile

Construisons 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 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 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 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 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}
}
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 Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur Rust en ligne