Menu
Coddy logo textTech

Contraintes multiples

Fait partie de la section Object Oriented Programming du Journey Rust de Coddy. Leçon 41 sur 61.

Parfois, une seule borne de trait ne suffit pas. Vous pourriez avoir besoin d'un type générique qui peut à la fois être affiché et fournir un résumé. Rust vous permet d'exiger plusieurs traits en utilisant la syntaxe +.

Voici comment spécifier qu'un type doit implémenter deux traits :

use std::fmt::Display;

trait Summary {
    fn summarize(&self) -> String;
}

fn announce<T: Display + Summary>(item: T) {
    println!("Breaking news: {}", item);
    println!("Summary: {}", item.summarize());
}

La contrainte T: Display + Summary signifie que « T doit implémenter à la fois Display et Summary ». À l'intérieur de la fonction, vous pouvez utiliser les fonctionnalités des deux traits — l'affichage avec {} (provenant de Display) et l'appel à summarize() (provenant de Summary).

Vous pouvez enchaîner autant de traits que nécessaire :

fn process<T: Display + Summary + Clone>(item: T) {
    // Peut afficher, résumer ET cloner
}

Ce pattern est essentiel lorsque votre fonction repose sur plusieurs comportements. Plutôt que d'accepter n'importe quel type en espérant que cela fonctionne, vous déclarez explicitement les capacités exactes requises — et le compilateur l'impose au moment de la compilation.

challenge icon

Défi

Facile

Construisons un système d'inspection de produits qui exige que les articles possèdent plusieurs capacités ! Vous allez créer une fonction générique qui n'accepte que les types implémentant à la fois un trait personnalisé et un trait standard, démontrant ainsi comment la syntaxe + combine plusieurs bornes (bounds).

Vous organiserez votre code sur deux fichiers :

  • product.rs : Définissez un trait public Inspectable avec une méthode appelée inspect qui prend &self et retourne un String contenant les détails de l'inspection. Créez ensuite une structure publique Gadget avec des champs publics name (String) et serial (u32). Votre Gadget doit implémenter à la fois Inspectable (retournant "Inspecting: {}" avec le nom) et std::fmt::Display (formaté comme "{} (SN: {})"). Enfin, créez une fonction générique publique appelée full_report qui accepte n'importe quel type T implémentant à la fois Display et Inspectable. Cette fonction doit imprimer deux lignes : d'abord l'article en utilisant le formateur {}, puis le résultat de l'appel à inspect().
  • main.rs : Importez votre module product et créez une instance de Gadget en utilisant les entrées fournies. Appelez full_report avec votre gadget pour montrer qu'il satisfait aux exigences des deux traits.

La puissance des bornes multiples est que votre fonction full_report peut utiliser les capacités des deux traits — afficher l'article proprement ET obtenir les détails de l'inspection — le tout garanti au moment de la compilation.

Votre sortie devrait afficher à la fois le format d'affichage et le résultat de l'inspection :

{name} (SN: {serial})
Inspecting: {name}

Par exemple, avec les entrées Smartwatch et 98765 :

Smartwatch (SN: 98765)
Inspecting: Smartwatch

Vous recevrez deux entrées : le nom du gadget et le numéro de série (à analyser comme un u32).

Essayez vous-même

mod product;

use product::{Gadget, full_report};

fn main() {
    // Lire les entrées
    let mut name = String::new();
    std::io::stdin().read_line(&mut name).expect("Failed to read line");
    let name = name.trim().to_string();
    
    let mut serial_input = String::new();
    std::io::stdin().read_line(&mut serial_input).expect("Failed to read line");
    let serial: u32 = serial_input.trim().parse().expect("Failed to parse serial");
    
    // TODO: Créer une instance de Gadget avec le nom et le numéro de série
    
    // TODO: Appeler full_report avec votre gadget
}
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

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