Menu
Coddy logo textTech

Dispatch dynamique

Fait partie de la section Programmation Orientée Objet du Journey Rust de Coddy. Leçon 45 sur 61.

Lorsque vous utilisez des génériques avec des contraintes de trait comme <T: Summary>, Rust détermine le type exact au moment de la compilation. C’est ce qu’on appelle la résolution statique : le compilateur génère du code spécialisé pour chaque type concret que vous utilisez. C’est rapide, mais il y a une limitation : une variable ne peut contenir qu’un seul type spécifique.

Que faire si vous avez besoin d’une seule variable capable de contenir des types différents à l’exécution ? C’est là qu’interviennent les objets de trait. En utilisant Box<dyn Trait>, vous pouvez stocker tout type qui implémente le trait :

trait Speak {
    fn speak(&self) -> String;
}

struct Dog;
struct Cat;

impl Speak for Dog {
    fn speak(&self) -> String { String::from("Woof!") }
}

impl Speak for Cat {
    fn speak(&self) -> String { String::from("Meow!") }
}

fn main() {
    let animal: Box<dyn Speak> = Box::new(Dog);
    println!("{}", animal.speak());  // "Woof!"
    
    let animal: Box<dyn Speak> = Box::new(Cat);
    println!("{}", animal.speak());  // "Meow!"
}

Le mot-clé dyn indique une répartition dynamique : Rust détermine quelle méthode appeler lors de l’exécution plutôt qu’à la compilation. Le Box est nécessaire, car les objets de trait n’ont pas de taille connue ; Box fournit un pointeur de taille fixe.

Voyez les choses ainsi : les génériques disent « je fonctionne avec le type T », tandis que les objets de trait disent « je fonctionne avec tout ce qui peut faire ceci ». Le compromis est un léger coût à l’exécution en échange de la flexibilité nécessaire pour gérer différents types avec la même variable.

challenge icon

Défi

Facile

Construisons un système de location de véhicules qui démontre la puissance de la répartition dynamique ! Tu vas créer un trait qui définit ce que tout véhicule louable peut faire, puis utiliser Box<dyn Trait> pour stocker différents types de véhicules dans la même variable.

Tu organiseras ton code sur deux fichiers :

  • vehicle.rs : définis un trait public Rentable avec une méthode rental_info qui prend &self et renvoie une String. Crée ensuite deux structures publiques :
    • Car : avec un champ public model (String). Sa méthode rental_info doit renvoyer Car: {model}
    • Bike : avec un champ public brand (String). Sa méthode rental_info doit renvoyer Bike: {brand}
  • main.rs : importe ton module de véhicule et utilise les entrées pour démontrer la répartition dynamique. Crée une variable Box<dyn Rentable> qui contient d'abord un Car, affiche ses informations de location, puis réassigne la même variable pour qu'elle contienne un Bike et affiche à nouveau ses informations de location.

La magie, ici, est qu'une seule variable de type Box<dyn Rentable> peut contenir soit un Car, soit un Bike : Rust détermine quelle méthode rental_info appeler lors de l'exécution. C'est la répartition dynamique en action !

Ta sortie doit afficher les informations des deux véhicules :

Car: {model}
Bike: {brand}

Par exemple, avec les entrées Tesla Model 3 et Trek :

Car: Tesla Model 3
Bike: Trek

Tu recevras deux entrées : le modèle de la voiture et la marque du vélo.

Essayez vous-même

mod vehicle;

use vehicle::{Rentable, Car, Bike};

fn main() {
    // Lire l'entrée
    let mut car_model = String::new();
    std::io::stdin().read_line(&mut car_model).expect("Failed to read line");
    let car_model = car_model.trim().to_string();
    
    let mut bike_brand = String::new();
    std::io::stdin().read_line(&mut bike_brand).expect("Failed to read line");
    let bike_brand = bike_brand.trim().to_string();
    
    // TODO: Créer une variable Box<dyn Rentable> qui contient une Car
    // Afficher ses infos de location en utilisant la méthode rental_info()
    
    // TODO: Réassigner la même variable pour contenir un Bike
    // Afficher à nouveau ses infos de location
    
}
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