Trait di uguaglianza
Fa parte della sezione Programmazione orientata agli oggetti del percorso Rust di Coddy. Lezione 38 di 61.
Il confronto tra due istanze di una struct personalizzata con == non funziona per impostazione predefinita in Rust. Il compilatore non sa come determinare se due struct sono uguali. Devi indicarglielo implementando il trait PartialEq.
Come Debug e Copy, puoi derivare automaticamente PartialEq:
#[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 viene derivato, PartialEq confronta ogni campo della struct. Due istanze sono uguali solo se tutti i campi corrispondenti coincidono.
Incontrerai anche Eq, che è un trait marcatore che indica l'uguaglianza totale, ovvero che ogni valore è uguale a sé stesso. La maggior parte dei tipi soddisfa questa proprietà, ma i numeri in virgola mobile no (perché NaN != NaN). Per le struct con campi interi, puoi derivare entrambi senza problemi:
#[derive(PartialEq, Eq)]
struct Coordinate {
x: i32,
y: i32,
}
Eq non ha metodi propri. Indica semplicemente che il tipo ha un’uguaglianza riflessiva. Alcune funzionalità della libreria standard richiedono Eq oltre a PartialEq, quindi è comune derivarli entrambi per i tipi che soddisfano i requisiti.
Sfida
FacileCostruiamo un sistema di corrispondenza dei colori che mostri come i trait PartialEq e Eq consentono di confrontare istanze di struct!
Creerai due file per organizzare la logica di confronto dei colori:
color.rs: Definisci una struct pubblicaColorcon tre campi pubblici:red,greeneblue(tuttiu8). Deriva siaPartialEqsiaEq, così da poter confrontare due colori usando==. Quando vengono derivati, Rust considererà uguali due colori solo se tutte e tre le componenti RGB corrispondono esattamente.main.rs: Includi il tuo modulo dei colori e crea due istanze diColorusando gli input forniti. Confrontale usando==e stampa se corrispondono oppure no.
L'output dovrebbe indicare se i due colori sono uguali:
Color 1: rgb({r1}, {g1}, {b1})
Color 2: rgb({r2}, {g2}, {b2})
Colors match: {true/false}Ad esempio, con gli input 255, 128, 0, 255, 128, 0:
Color 1: rgb(255, 128, 0)
Color 2: rgb(255, 128, 0)
Colors match: trueE con gli input 100, 100, 100, 200, 200, 200:
Color 1: rgb(100, 100, 100)
Color 2: rgb(200, 200, 200)
Colors match: falseRiceverai sei input: i valori RGB del primo colore (tre valori), seguiti dai valori RGB del secondo colore (tre valori). Analizza ciascuno come u8.
Provalo tu
mod color;
use color::Color;
fn main() {
// Leggi i sei valori 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 due istanze di Color usando i valori ottenuti
// TODO: Stampa Color 1 nel formato: Color 1: rgb(r, g, b)
// TODO: Stampa Color 2 nel formato: Color 2: rgb(r, g, b)
// TODO: Confronta i due colori usando == e stampa: Colors match: {true/false}
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Metodi e comportamento
Introduzione ai blocchi implIl parametro selfMetodi mutabiliFunzioni associateBlocchi impl multipliConcatenamento di metodiRiepilogo - Azioni sul rettangolo4Progetto: animale domestico virtuale
Definire l'animaleNutrire l'animale7Trait standard
Il trait DebugIl trait DisplayClone e CopyTrait di uguaglianzaRiepilogo - Punto stampabile10Progetto: sistema di documenti
Il trait DrawComponente di testo2Incapsulamento e moduli
Nozioni di base sui moduliLa parola chiave publicCampi privatiGetterSetterRiepilogo - Armadietto sicuro5Generics
Struct genericheMetodi genericiPiù tipi genericiFunzioni genericheRipasso - Punto di coordinate8I Trait come vincoli
Sintassi dei vincoli sui traitVincoli multipliLa clausola whereRestituire tipi con i traitRiepilogo - Stampante generica11Modelli di progettazione in Rust
Pattern NewtypeComposizioneIl trait DropFrom e IntoRipasso - Mock con smart pointer3Enumerazioni avanzate
Enumerazioni con datiMetodi sulle enumerazioniCorrispondenza delle varianti con datiL'enumerazione Option ripresaRiepilogo - enumerazione Shape6Definizione dei trait
Che cos’è un trait?Implementare i traitImplementazioni predefiniteSovrascrivere le implementazioni predefiniteTrait con parametriRiepilogo - Lettore multimedialeEsercitati da solo: Compilatore Rust online