Traits de igualdad
Parte de la sección Programación Orientada a Objetos del Journey de Rust de Coddy. Lección 38 de 61.
Comparar dos instancias de una estructura personalizada con == no funciona de forma predeterminada en Rust. El compilador no sabe cómo determinar si dos estructuras son iguales. Debes indicárselo implementando el rasgo PartialEq.
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 encontrarás Eq, que es un trait marcador que indica igualdad total, lo que significa que cada valor es igual a sí mismo. La mayoría de los tipos cumplen esto, pero los números de coma flotante no (porque NaN != NaN). Para las estructuras con campos enteros, puedes derivar ambos de forma segura:
#[derive(PartialEq, Eq)]
struct Coordinate {
x: i32,
y: i32,
}
Eq no tiene métodos propios. Simplemente indica que el tipo tiene igualdad reflexiva. Algunas características de la biblioteca estándar requieren Eq además de PartialEq, por lo que es habitual derivar ambos conjuntamente para los tipos que cumplen los requisitos.
Desafío
Fácil¡Construyamos un sistema de comparación de colores que demuestre cómo los traits PartialEq y Eq permiten comparar instancias de estructuras!
Crearás dos archivos para organizar la lógica de comparación de colores:
color.rs: Define una estructuraColorpública con tres campos públicos:red,greenyblue(todosu8). Deriva tantoPartialEqcomoEqpara 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: Incluye tu módulo de colores y crea dos instancias deColorusando 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: trueY con las entradas 100, 100, 100, 200, 200, 200:
Color 1: rgb(100, 100, 100)
Color 2: rgb(200, 200, 200)
Colors match: falseRecibirás seis entradas: los valores RGB del primer color (tres valores), seguidos de los valores RGB del segundo color (tres valores). Analiza cada uno como u8.
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 parseados
// 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: Compare the two colors using == and print: Colors match: {true/false}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Métodos y Comportamiento
Intro a Bloques de ImplementaciónEl Parámetro SelfMétodos MutablesFunciones AsociadasMúltiples Bloques de ImplementaciónEncadenamiento de MétodosResumen - Acciones de Rectángulo4Proyecto: Mascota virtual
Definir la mascotaAlimentar a la mascota7Traits estándar
El trait DebugEl trait DisplayClone y CopyTraits de igualdadResumen - Punto imprimible10Proyecto: Sistema de documentos
El Trait DrawComponente de texto2Encapsulamiento y módulos
Conceptos básicos de módulosLa palabra clave PublicCampos privadosGettersSettersRepaso - Casillero seguro5Genéricos
Estructuras genéricasMétodos genéricosMúltiples tipos genéricosFunciones genéricasResumen - Punto de coordenadas8Traits como límites
Sintaxis de límites de traitsLímites múltiplesLa cláusula whereRetornar tipos con traitsResumen: Impresora genérica11Patrones de diseño en Rust
Patrón NewtypeComposiciónEl Trait DropFrom e IntoResumen - Mock de Smart Pointer3Enums avanzados
Enums con datosMétodos en EnumsCoincidencia de variantes de datosEl Enum Option revisitadoResumen - Enum Shape6Definición de Traits
¿Qué es un Trait?Implementación de TraitsImplementaciones por defectoSobrescribir valores por defectoTraits con parámetrosResumen - Reproductor multimediaPractica por tu cuenta: Compilador de Rust online