Menu
Coddy logo textTech

Les traits d'égalité

Fait partie de la section Object Oriented Programming 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 Debug et Copy, vous pouvez dériver PartialEq automatiquement :

#[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 seulement si tous leurs champs correspondants sont identiques.

Vous rencontrerez également Eq, qui est un trait marqueur indiquant l'égalité totale—ce qui signifie que chaque valeur est égale à elle-même. La plupart des types satisfont à cela, mais pas les nombres à virgule flottante (car NaN != NaN). Pour les structures avec 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 pas de méthodes propres — il signale 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 y sont éligibles.

challenge icon

Défi

Facile

Construisons un système de correspondance de couleurs qui démontre comment les traits PartialEq et Eq permettent la comparaison entre des instances de structures !

Vous allez créer deux fichiers pour organiser votre logique de comparaison de couleurs :

  • color.rs : Définissez une structure publique Color avec trois champs publics : red, green, et blue (tous de type u8). Dérivez à la fois PartialEq et Eq afin que deux couleurs puissent être comparées à l'aide de ==. Lorsqu'ils sont dérivés, Rust considérera que deux couleurs sont égales uniquement si les trois composants RVB correspondent exactement.
  • main.rs : Importez votre module de couleur et créez deux instances de Color en utilisant les entrées fournies. Comparez-les en utilisant == et affichez si elles correspondent ou non.

Votre 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: true

Et avec les entrées 100, 100, 100, 200, 200, 200 :

Color 1: rgb(100, 100, 100)
Color 2: rgb(200, 200, 200)
Colors match: false

Vous recevrez six entrées : les valeurs RVB pour la première couleur (trois valeurs), suivies des valeurs RVB pour la seconde couleur (trois valeurs). Analysez chacune d'elles comme un u8.

Aide-mémoire

Pour comparer des structures personnalisées à l'aide de ==, implémentez le trait PartialEq en le dérivant :

#[derive(PartialEq)]
struct Coordinate {
    x: i32,
    y: i32,
}

let a = Coordinate { x: 5, y: 10 };
let b = Coordinate { x: 5, y: 10 };

println!("{}", a == b);  // true

Lorsqu'il est dérivé, PartialEq compare tous les champs — deux instances sont égales uniquement si tous les champs correspondants correspondent.

Le trait Eq est un trait marqueur indiquant une égalité totale (chaque valeur est égale à elle-même). La plupart des types satisfont à cela, à l'exception des nombres à virgule flottante (car NaN != NaN). Pour les structures avec des champs de type entier, dérivez les deux traits ensemble :

#[derive(PartialEq, Eq)]
struct Coordinate {
    x: i32,
    y: i32,
}

Eq n'a pas de méthodes — il signale une égalité réflexive. Certaines fonctionnalités de la bibliothèque standard nécessitent Eq en plus de PartialEq.

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: Comparer les deux couleurs en utilisant == et afficher : Colors match: {true/false}
}
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