Les traits d'égalité
Fait partie de la section Programmation Orientée Objet du Journey Rust de Coddy. Leçon 38 sur 61.
Comparer deux instances d’une structure personnalisée avec == ne fonctionne pas par défaut en Rust. Le compilateur ne sait pas comment déterminer si deux structures sont égales. Vous devez le lui indiquer en implémentant le trait PartialEq.
Comme avec Debug et Copy, vous pouvez dériver automatiquement PartialEq :
#[derive(PartialEq)]
struct Coordinate {
x: i32,
y: i32,
}
let a = Coordinate { x: 5, y: 10 };
let b = Coordinate { x: 5, y: 10 };
let c = Coordinate { x: 3, y: 7 };
println!("{}", a == b); // true
println!("{}", a == c); // false
Lorsqu’il est dérivé, PartialEq compare chaque champ de la structure. Deux instances sont égales uniquement si tous leurs champs correspondants concordent.
Vous rencontrerez également Eq, qui est un trait marqueur indiquant une égalité totale, ce qui signifie que chaque valeur est égale à elle-même. La plupart des types satisfont cette condition, mais les nombres à virgule flottante ne la satisfont pas (car NaN != NaN). Pour les structures comportant des champs entiers, vous pouvez dériver les deux en toute sécurité :
#[derive(PartialEq, Eq)]
struct Coordinate {
x: i32,
y: i32,
}
Eq n'a aucune méthode qui lui soit propre. Il indique simplement que le type possède une égalité réflexive. Certaines fonctionnalités de la bibliothèque standard nécessitent Eq en plus de PartialEq ; il est donc courant de dériver les deux ensemble pour les types qui s'y prêtent.
Défi
FacileConstruisons un système de correspondance des couleurs qui montre comment les traits PartialEq et Eq permettent de comparer des instances de structures !
Tu vas créer deux fichiers pour organiser ta logique de comparaison des couleurs :
color.rs: définis une structureColorpublique avec trois champs publics :red,greenetblue(tous de typeu8). Dérive à la foisPartialEqetEqafin que deux couleurs puissent être comparées à l'aide de==. Lorsqu'ils sont dérivés, Rust considère que deux couleurs sont égales uniquement si les trois composantes RGB correspondent exactement.main.rs: importe ton module de couleurs et crée deux instances deColorà l'aide des entrées fournies. Compare-les avec==et affiche si elles correspondent ou non.
Ta sortie doit indiquer si les deux couleurs sont identiques :
Color 1: rgb({r1}, {g1}, {b1})
Color 2: rgb({r2}, {g2}, {b2})
Colors match: {true/false}Par exemple, avec les entrées 255, 128, 0, 255, 128, 0 :
Color 1: rgb(255, 128, 0)
Color 2: rgb(255, 128, 0)
Colors match: trueEt avec les entrées 100, 100, 100, 200, 200, 200 :
Color 1: rgb(100, 100, 100)
Color 2: rgb(200, 200, 200)
Colors match: falseTu recevras six entrées : les valeurs RGB de la première couleur (trois valeurs), suivies des valeurs RGB de la seconde couleur (trois valeurs). Analyse chacune d'elles comme un u8.
Essayez vous-même
mod color;
use color::Color;
fn main() {
// Lire les six valeurs RGB
let mut input = String::new();
std::io::stdin().read_line(&mut input).expect("Failed to read line");
let r1: u8 = input.trim().parse().expect("Invalid input");
input.clear();
std::io::stdin().read_line(&mut input).expect("Failed to read line");
let g1: u8 = input.trim().parse().expect("Invalid input");
input.clear();
std::io::stdin().read_line(&mut input).expect("Failed to read line");
let b1: u8 = input.trim().parse().expect("Invalid input");
input.clear();
std::io::stdin().read_line(&mut input).expect("Failed to read line");
let r2: u8 = input.trim().parse().expect("Invalid input");
input.clear();
std::io::stdin().read_line(&mut input).expect("Failed to read line");
let g2: u8 = input.trim().parse().expect("Invalid input");
input.clear();
std::io::stdin().read_line(&mut input).expect("Failed to read line");
let b2: u8 = input.trim().parse().expect("Invalid input");
// TODO: Créer deux instances de Color en utilisant les valeurs analysées
// TODO: Afficher Color 1 au format : Color 1: rgb(r, g, b)
// TODO: Afficher Color 2 au format : Color 2: rgb(r, g, b)
// TODO: Compare the two colors using == and print: Colors match: {true/false}
}
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
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édiaEntraînez-vous par vous-même : Compilateur Rust en ligne