I have struct with several fields one of them is f64
. I want to compare this field with (a.f -b.f).abs() < eps
and reuse auto genetated code by derive(ParialEq)
for comparing other field, is it possible somehow?
No, you have to implement PartialEq
yourself for your struct. Of course you can defer to the existing PartialEq
implementations for the fields which have those, but you would have to do that manually.
Actually, there is a nice pattern to do this, though it won't save a lot of typing in this case. You can define a local struct and reuse it's derive
:
struct Bad {
x: i32,
y: String,
z: f64
}
impl PartialEq for Bad {
fn eq(&self, other: &Bad) -> bool {
#[derive(PartialEq)]
struct Good<'a> {
x: &'a i32,
y: &'a String,
}
fn to_good(bad: &Bad) -> Good { Good { x: &bad.x, y: &bad.y } }
assert!(!self.z.is_nan() && !other.z.is_nan());
to_good(self) == to_good(other) && self.z == other.z
}
}
And keep in mind that (x - y).abs() < eps
is not an equivalence relation on floats.
1 Like
Another, more succinct alternative is to wrap all f64's in a MyFloat
struct for which you can define PartialEq
however you want. And then you can #[derive(PartialEq)]
on structs containing instances of MyFloat
.
struct MyFloat(f64);
impl PartialEq for MyFloat {
fn eq(&self, other: &MyFloat) -> bool {
// ..
}
}
#[derive(PartialEq)]
struct MyStruct {
x: i32,
y: String,
z: MyFloat,
}
The only drawback is that you would have to refer to the float as my_struct.z.0
instead of my_struct.z
.