error[E0308]: mismatched types
--> src\main.rs:2:13
|
1 | fn eq_zero<T: std::cmp::PartialEq>(a:T) -> bool {
| - this type parameter
2 | if a == 0 {
| ^ expected type parameter `T`, found integer
|
= note: expected type parameter `T`
found type `{integer}`
When you write 0 that's actually an i32 constant, and because your function requires T: PartialEq (i.e. T is only comparable with itself) you get a type mismatch error.
rustc is effectively saying
You've written a function which accepts any arbitrary T which can be compared for equality with another T but now you are trying to compare it with a i32, that doesn't make sense.
How you implement this is by letting the type system know what "zero" means for your particular T.
trait Zero {
const ZERO: Self;
}
impl Zero for i32 { const ZERO: Self = 0; }
impl Zero for f32 { const ZERO: Self = 0.0; }
Then you can update the function to accept any type which is comparable with itself (PartialEq) and has a zero value (Zero).
pub fn is_zero<T>(value: T) -> bool
where
T: PartialEq + Zero,
{
value == T::ZERO
}
This also lets you extend the is_zero() function to work with more than just primitive numbers. For example:
fn main() {
assert_eq!(is_zero(Point::new(3.14, 42.0)), false);
assert_eq!(is_zero(Point::new(0.0, 0.0)), true);
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Point {
x: f32,
y: f32,
}
impl Point {
pub const fn new(x: f32, y: f32) -> Self {
Point { x, y }
}
}
impl Zero for Point {
const ZERO: Self = Point::new(0.0, 0.0);
}
0 is not a floating point value. You would need '0.0'
Which is a good reminder that it is generally a bad idea to compare floating point values for equality. Very often things that you think should be equal are not.
In IEEE754 floating point arithmetics, 0 is not equals to -0. No, I remembered it wrong.
They're not identical, but considered equals.
Also 0.1 + 0.2 - 0.3 is not zero.