Menu
Coddy logo textTech

Traits de Igualdade

Parte da seção Object Oriented Programming do Journey de Rust da Coddy — lição 38 de 61.

Comparar duas instâncias de uma struct personalizada com == não funciona por padrão no Rust. O compilador não sabe como determinar se duas structs são iguais — você precisa dizer a ele implementando a trait PartialEq.

Assim como Debug e Copy, você pode derivar PartialEq automaticamente:

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

Quando derivado, PartialEq compara cada campo da struct. Duas instâncias são iguais apenas se todos os seus campos correspondentes coincidirem.

Você também encontrará o Eq, que é uma trait de marcação que indica igualdade total—o que significa que cada valor é igual a si mesmo. A maioria dos tipos satisfaz isso, mas números de ponto flutuante não (porque NaN != NaN). Para structs com campos de números inteiros, você pode derivar ambos com segurança:

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

Eq não possui métodos próprios — ele simplesmente sinaliza que o tipo possui igualdade reflexiva. Alguns recursos da biblioteca padrão exigem Eq além de PartialEq, por isso é comum derivar ambos juntos para tipos que se qualificam.

challenge icon

Desafio

Fácil

Vamos construir um sistema de correspondência de cores que demonstra como as traits PartialEq e Eq permitem a comparação entre instâncias de structs!

Você criará dois arquivos para organizar sua lógica de comparação de cores:

  • color.rs: Defina uma struct Color pública com três campos públicos: red, green e blue (todos u8). Derive tanto PartialEq quanto Eq para que duas cores possam ser comparadas usando ==. Quando derivado, o Rust considerará duas cores iguais apenas se todos os três componentes RGB coincidirem exatamente.
  • main.rs: Importe seu módulo de cores e crie duas instâncias de Color usando as entradas fornecidas. Compare-as usando == e imprima se elas coincidem ou não.

Sua saída deve indicar se as duas cores são iguais:

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

Por exemplo, com as entradas 255, 128, 0, 255, 128, 0:

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

E com as entradas 100, 100, 100, 200, 200, 200:

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

Você receberá seis entradas: os valores RGB para a primeira cor (três valores), seguidos pelos valores RGB para a segunda cor (três valores). Analise cada um como u8.

Folha de consulta

Para comparar structs personalizadas usando ==, implemente a trait PartialEq derivando-a:

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

Quando derivada, a PartialEq compara todos os campos—duas instâncias são iguais apenas se todos os campos correspondentes coincidirem.

A trait Eq é uma trait de marcação (marker trait) que indica igualdade total (cada valor é igual a si mesmo). A maioria dos tipos satisfaz isso, exceto números de ponto flutuante (porque NaN != NaN). Para structs com campos de números inteiros, derive ambas as traits juntas:

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

A Eq não possui métodos—ela sinaliza igualdade reflexiva. Alguns recursos da biblioteca padrão exigem Eq além de PartialEq.

Experimente você mesmo

mod color;

use color::Color;

fn main() {
    // Lê os seis valores 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: Criar duas instâncias de Color usando os valores analisados

    // TODO: Imprimir Color 1 no formato: Color 1: rgb(r, g, b)

    // TODO: Imprimir Color 2 no formato: Color 2: rgb(r, g, b)

    // TODO: Comparar as duas cores usando == e imprimir: Colors match: {true/false}
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Object Oriented Programming