I am reading the Rust book and trying to understand use cases for PartialEq
and Eq
traits.
I realise that PartialEq
is for relations which are not necessarily reflexive (i.e. there can be such x
that x != x
) and that Eq
is a marker trait which says that relation is also reflexive (and now it is a proper equivalence relation).
The books gives an example where PartialEq
is not enough and Eq
is required: HashMap<K, V>
lookups. Indeed, if we use as a key a data type which only implements PartialEq
(for example floating point number), we would get in trouble when we try to use NaN
as a key, since we won't be able to find it.
Now, I am trying to understand what feature of a lookup makes it require Eq
. I may be able to understand it better if I find an example of code which does not require Eq
.
The book says that assert_eq!
requires only PartialEq
so that we are able to compare things for equality. But if we write assert_eq!(f64::NAN, some_code_producing_nan());
in a test, the test will always fail. We have the same basic issue as with using a PartialEq
key in a HashMap
, but for some reason it is considered appropriate here.
What is an example of a reasonable function which requires only PartialEq
and adding Eq
is not desirable/does not make sense?
If there are no such use cases, then why do we care about splitting it into two traits PartialEq
/ Eq
? Haskell, for example, just has Eq
.
Trait for equality comparisons which are partial equivalence relations. This trait allows for partial equality, for types that do not have a full equivalence relation. For example, in floating point numbers NaN != NaN, so floating point types implement PartialEq but not Eq.
We can use the eq(), eq_ignore_ascii_case() and == to compare strings in Rust.
Deciding when to use PartialEq
vs Eq
should be based on whether the use requires that x == x
.
The question is not about whether it is possible to compare x
to x
but rather if that comparison happens, does the use depend on x==x
always holding? If the answer is yes, use Eq
. Otherwise prefer the weaker constraint PartialEq
.
assert_eq!
doesn't depend on x==x
always holding so there is no need to force that constraint on the caller. As OP succinctly mentioned 2 examples in the comments:
if we do
assert_eq!(NAN, produces_nan())
- it's our problem that it givesfalse
, but if we do a lookup of aNAN
key in aHashMap
, it would be a problem of theHashMap
, because it would violate its lookup contract (that it should be able to find all the keys put in the map)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With