Le trait Debug
Fait partie de la section Object Oriented Programming du Journey Rust de Coddy — leçon 35 sur 61.
La bibliothèque standard de Rust est fournie avec de nombreux traits prédéfinis qui fournissent des fonctionnalités communes. L'un des plus utiles pour le développement est le trait Debug, qui vous permet d'afficher le contenu d'une structure pour inspection.
Si vous essayez d'afficher directement une structure personnalisée, Rust ne saura pas comment l'afficher :
struct Player {
name: String,
score: u32,
}
let p = Player { name: String::from("Alice"), score: 100 };
println!("{:?}", p); // Erreur ! Debug n'est pas implémenté
Le formateur {:?} nécessite le trait Debug. Au lieu de l'implémenter manuellement, Rust fournit un raccourci — l'attribut #[derive]. Placez-le directement au-dessus de la définition de votre structure :
#[derive(Debug)]
struct Player {
name: String,
score: u32,
}
let p = Player { name: String::from("Alice"), score: 100 };
println!("{:?}", p); // Player { name: "Alice", score: 100 }
L'attribut #[derive(Debug)] indique au compilateur de générer automatiquement l'implémentation de Debug. Cela fonctionne tant que tous les champs de votre structure implémentent également Debug (ce que font la plupart des types standards).
Pour une sortie plus lisible avec des structures imbriquées, utilisez {:#?} pour un affichage soigné (pretty-printing) :
println!("{:#?}", p);
// Player {
// name: "Alice",
// score: 100,
// }
Dériver Debug est essentiel pendant le développement — cela vous permet d'inspecter rapidement vos données sans avoir à écrire de code de formatage personnalisé.
Défi
FacileRendons vos structures inspectables en dérivant le trait Debug ! Vous allez créer un système d'inventaire simple où les articles peuvent être affichés à des fins de débogage.
Vous organiserez votre code sur deux fichiers :
inventory.rs: Définissez une structure publiqueItemavec deux champs publics :name(String) etquantity(u32). Utilisez l'attribut#[derive(Debug)]pour implémenter automatiquement le trait Debug pour votre structure.main.rs: Importez votre module d'inventaire et créez une instance deItemen utilisant les entrées fournies. Affichez l'article en utilisant le formateur de débogage{:?}pour visualiser sa structure interne.
La beauté de la dérivation de Debug est que Rust génère automatiquement le code de formatage pour vous — aucune implémentation manuelle n'est nécessaire ! Votre structure a juste besoin de l'attribut, et elle devient affichable avec {:?}.
Votre sortie doit afficher l'article au format de débogage de Rust :
Item { name: "{name}", quantity: {quantity} }Par exemple, avec les entrées Keyboard et 15 :
Item { name: "Keyboard", quantity: 15 }Vous recevrez deux entrées : le nom de l'article et la quantité (à analyser comme un u32).
Aide-mémoire
Le trait Debug vous permet d'afficher le contenu d'une structure pour inspection en utilisant le formateur {:?}.
Utilisez l'attribut #[derive(Debug)] pour implémenter automatiquement Debug pour votre structure :
#[derive(Debug)]
struct Player {
name: String,
score: u32,
}
let p = Player { name: String::from("Alice"), score: 100 };
println!("{:?}", p); // Player { name: "Alice", score: 100 }
Pour une sortie joliment formatée avec une meilleure mise en forme, utilisez {:#?} :
println!("{:#?}", p);
// Player {
// name: "Alice",
// score: 100,
// }
L'attribut #[derive(Debug)] fonctionne tant que tous les champs de votre structure implémentent également Debug, ce qui est le cas de la plupart des types standard.
Essayez vous-même
mod inventory;
use inventory::Item;
fn main() {
// Lire l'entrée
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 quantity_str = String::new();
std::io::stdin().read_line(&mut quantity_str).expect("Failed to read line");
let quantity: u32 = quantity_str.trim().parse().expect("Failed to parse quantity");
// TODO: Créer une instance d'Item avec le nom et la quantité donnés
// TODO: Afficher l'item en utilisant le formateur de débogage {:?}
}
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
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édia