I'm trying to automatically "derive" comparison functionality for a simple struct like this:
#[derive(PartialEq, Eq)]
struct Vec3 {
x: f64,
y: f64,
z: f64,
}
However, Rust 1.15.1 complains:
error[E0277]: the trait bound `f64: std::cmp::Eq` is not satisfied
--> src/main.rs:3:5
|
3 | x: f64,
| ^^^^^^ the trait `std::cmp::Eq` is not implemented for `f64`
|
= note: required by `std::cmp::AssertParamIsEq`
What exactly am I supposed to do to allow the derivation of a default implementation here?
Rust intentionally does not implement Eq
for float types. This reddit discussion may shed some more light on why, but the tl;dr is that floating point numbers aren't totally orderable so bizarre edge cases are unavoidable.
However, if you want to add comparison to your struct, you can derive PartialOrd
instead. This will give you implementations of the comparative and equality operators:
#[derive(PartialEq, PartialOrd)]
struct Vec3 {
x: f64,
y: f64,
z: f64,
}
fn main() {
let a = Vec3 { x: 1.0, y: 1.1, z: 1.0 };
let b = Vec3 { x: 2.0, y: 2.0, z: 2.0 };
println!("{}", a < b); //true
println!("{}", a <= b); //true
println!("{}", a == b); //false
}
The difference between Eq
and PartialEq
(and hence between Ord
and PartialOrd
) is that Eq
requires that the ==
operator form an equivalence relation, whereas PartialOrd
only requires that ==
and !=
are inverses. So just as with floats themselves, you should keep that in mind when doing comparisons on instances of your struct.
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