Menu
Coddy logo textTech

Equality Traits

Part of the Object Oriented Programming section of Coddy's Rust journey — lesson 38 of 61.

Comparing two instances of a custom struct with == doesn't work by default in Rust. The compiler doesn't know how to determine if two structs are equal—you need to tell it by implementing the PartialEq trait.

Like Debug and Copy, you can derive PartialEq automatically:

#[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

When derived, PartialEq compares each field of the struct. Two instances are equal only if all their corresponding fields match.

You'll also encounter Eq, which is a marker trait that indicates total equality—meaning every value equals itself. Most types satisfy this, but floating-point numbers don't (because NaN != NaN). For structs with integer fields, you can safely derive both:

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

Eq has no methods of its own—it simply signals that the type has reflexive equality. Some standard library features require Eq in addition to PartialEq, so it's common to derive both together for types that qualify.

challenge icon

Challenge

Easy

Let's build a color matching system that demonstrates how the PartialEq and Eq traits enable comparison between struct instances!

You'll create two files to organize your color comparison logic:

  • color.rs: Define a public Color struct with three public fields: red, green, and blue (all u8). Derive both PartialEq and Eq so that two colors can be compared using ==. When derived, Rust will consider two colors equal only if all three RGB components match exactly.
  • main.rs: Bring in your color module and create two Color instances using the inputs provided. Compare them using == and print whether they match or not.

Your output should indicate whether the two colors are the same:

Color 1: rgb({r1}, {g1}, {b1})
Color 2: rgb({r2}, {g2}, {b2})
Colors match: {true/false}

For example, with inputs 255, 128, 0, 255, 128, 0:

Color 1: rgb(255, 128, 0)
Color 2: rgb(255, 128, 0)
Colors match: true

And with inputs 100, 100, 100, 200, 200, 200:

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

You will receive six inputs: the RGB values for the first color (three values), followed by the RGB values for the second color (three values). Parse each as u8.

Cheat sheet

To compare custom structs using ==, implement the PartialEq trait by deriving it:

#[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

When derived, PartialEq compares all fields—two instances are equal only if all corresponding fields match.

The Eq trait is a marker trait indicating total equality (every value equals itself). Most types satisfy this, except floating-point numbers (because NaN != NaN). For structs with integer fields, derive both traits together:

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

Eq has no methods—it signals reflexive equality. Some standard library features require Eq in addition to PartialEq.

Try it yourself

mod color;

use color::Color;

fn main() {
    // Read the six RGB values
    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: Create two Color instances using the parsed values

    // TODO: Print Color 1 in the format: Color 1: rgb(r, g, b)

    // TODO: Print Color 2 in the format: Color 2: rgb(r, g, b)

    // TODO: Compare the two colors using == and print: Colors match: {true/false}
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming