In Rust ontstaan de traits PartialEq en Eq uit de filosofie van type safety — alle fundamentele operaties voor collecties (HashMap, HashSet) zijn gebaseerd op een strikte definitie van gelijkheid. De traits bepalen of objecten van twee types vergeleken kunnen worden met behulp van == en of het type verplicht is om "volledige" gelijkheid (Eq) of "gedeeltelijke" gelijkheid (PartialEq) te implementeren.
Een verkeerde implementatie van PartialEq/Eq leidt tot onjuiste werking van collecties, waarbij basiswiskundige eigenschappen worden geschonden: vergelijking met zichzelf, symmetrie, transitiviteit. Daarnaast kan een onjuiste Eq leiden tot het "verliezen" van objecten in collecties of het ontstaan van onverwachte duplicaten.
PartialEq wordt geïmplementeerd voor types waarbij vergelijking mogelijk is, maar niet voor alle waarden (bijvoorbeeld f32, waar NaN != NaN). Eq is alleen bedoeld voor "strikte" (totale) relaties. Gebruikersdefinities moeten vergelijking implementeren in strikte overeenstemming met deze contracten.
Voorbeeldcode:
#[derive(PartialEq, Eq)] struct Point { x: i32, y: i32, } let p1 = Point { x: 1, y: 2 }; let p2 = Point { x: 1, y: 2 }; assert!(p1 == p2); // true
Belangrijke eigenschappen:
Waarom implementeert de standaardbibliotheek voor het type f32 alleen PartialEq, maar niet Eq?
Omdat volgens IEEE-754 NaN != NaN, dat wil zeggen dat de eigenschap x == x voor alle x niet wordt gerespecteerd, en dit is een noodzakelijke eigenschap voor Eq.
Is het verplicht om Eq expliciet te implementeren als PartialEq handmatig is geïmplementeerd?
Ja, als het type volledige gelijkheid ondersteunt (x == x is altijd true), moet je ook handmatig Eq implementeren, anders weigeren sommige structuren de compilatie met jouw type.
Kan een gebruiker PartialEq "niet-symmetrisch" implementeren (x == y, maar y != x)?
Technisch gezien ja, maar dit leidt tot onjuiste werking van collecties en wordt beschouwd als een bug.
** Negatieve case
Een gebruiker implementeerde PartialEq voor een type dat alleen op één veld vergelijkingen maakt, terwijl andere worden genegeerd. Als gevolg hiervan "verliest" HashSet duplicaten.
Voordelen:
Nadelen:
** Positieve case
Gebruik #[derive(PartialEq, Eq)] of implementeer een eigen versie van de vergelijking die rekening houdt met de gehele bedrijfslogica, waarbij de vereiste eigenschappen worden gewaarborgd.
Voordelen:
Nadelen: