Menu
Coddy logo textTech

Traits de igualdad

Parte de la sección Object Oriented Programming del Journey de Rust de Coddy — lección 38 de 61.

Comparar dos instancias de una estructura personalizada con == no funciona por defecto en Rust. El compilador no sabe cómo determinar si dos estructuras son iguales; debes indicárselo implementando el PartialEq trait.

Al igual que Debug y Copy, puedes derivar PartialEq automáticamente:

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

Cuando se deriva, PartialEq compara cada campo de la estructura. Dos instancias son iguales solo si todos sus campos correspondientes coinciden.

También te encontrarás con Eq, que es un rasgo marcador (marker trait) que indica igualdad total—lo que significa que cada valor es igual a sí mismo. La mayoría de los tipos cumplen con esto, pero los números de punto flotante no (porque NaN != NaN). Para estructuras con campos de enteros, puedes derivar ambos de forma segura:

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

Eq no tiene métodos propios; simplemente señala que el tipo tiene igualdad reflexiva. Algunas características de la biblioteca estándar requieren Eq además de PartialEq, por lo que es común derivar ambos juntos para los tipos que califican.

challenge icon

Desafío

Fácil

¡Vamos a construir un sistema de coincidencia de colores que demuestre cómo los traits PartialEq y Eq permiten la comparación entre instancias de structs!

Crearás dos archivos para organizar tu lógica de comparación de colores:

  • color.rs: Define un struct Color público con tres campos públicos: red, green, y blue (todos u8). Deriva tanto PartialEq como Eq para que dos colores puedan compararse usando ==. Al derivarlos, Rust considerará que dos colores son iguales solo si los tres componentes RGB coinciden exactamente.
  • main.rs: Importa tu módulo de color y crea dos instancias de Color utilizando las entradas proporcionadas. Compáralas usando == e imprime si coinciden o no.

Tu salida debe indicar si los dos colores son iguales:

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

Por ejemplo, con las entradas 255, 128, 0, 255, 128, 0:

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

Y con las entradas 100, 100, 100, 200, 200, 200:

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

Recibirás seis entradas: los valores RGB para el primer color (tres valores), seguidos de los valores RGB para el segundo color (tres valores). Procesa cada uno como u8.

Hoja de referencia

Para comparar structs personalizados usando ==, implementa el trait PartialEq derivándolo:

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

Cuando se deriva, PartialEq compara todos los campos; dos instancias son iguales solo si todos los campos correspondientes coinciden.

El trait Eq es un trait marcador que indica igualdad total (cada valor es igual a sí mismo). La mayoría de los tipos cumplen con esto, excepto los números de punto flotante (porque NaN != NaN). Para structs con campos de enteros, deriva ambos traits juntos:

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

Eq no tiene métodos; señala igualdad reflexiva. Algunas características de la biblioteca estándar requieren Eq además de PartialEq.

Pruébalo tú mismo

mod color;

use color::Color;

fn main() {
    // Lee los 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: Crea dos instancias de Color usando los valores analizados

    // TODO: Imprime Color 1 en el formato: Color 1: rgb(r, g, b)

    // TODO: Imprime Color 2 en el formato: Color 2: rgb(r, g, b)

    // TODO: Compara los dos colores usando == e imprime: Colors match: {true/false}
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Object Oriented Programming