fn compare<T: std::cmp::PartialOrd<i32>>(v: T) ->bool {
v > 10
}
fn main() {
let i : i32 = 9;
println!("{}", compare(i));
let j : u32 = 9;
println!("{}", compare(j));
}
want I want is to campare the v with 10, as long as the V is an number, but the code does not work as I expect:
error[E0277]: can't compare `u32` with `i32`
--> src/main.rs:15:28
|
7 | fn compare<T: std::cmp::PartialOrd<i32>>(v: T) ->bool {
| ------------------------- required by this bound in `compare`
...
15 | println!("{}", compare(j));
| ^ no implementation for `u32 < i32` and `u32 > i32`
|
= help: the trait `PartialOrd<i32>` is not implemented for `u32`
Then I tried this:
fn compare<T: std::cmp::PartialOrd<T>>(v: T) ->bool {
v > 10 as T
}
but than the compiler said:
error[E0605]: non-primitive cast: `i32` as `T`
--> src/main.rs:8:9
|
8 | v > 10 as T
| ^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
so how can I promise that all the T in the program is an primitive type? I didn't find any trait to do this.
use num_traits::FromPrimitive;
fn compare<T: PartialOrd + FromPrimitive>(v: T) -> bool {
let ten = T::from_i8(10).expect("unrepresentable");
v > ten
}
Please note that the conversion can fail. Obviously it won't fail if you convert 10 to u32, but for example, it will fail if you try to convert 257 to u8, so you need to account for that. The example above panics in this case.
This is some how not what I want, since 10 can be represent by u8, the converting will always success... What I want is to make type constrain on compile time, and except seems have performance issues. Any ways to do that? Or, will except in this case has extra overload?
You can't guarantee FromPrimitive will always succeed because your function is generic, and some exotic types may not be able to convert from 10 (e.g. a type with allowed range defined by const generics).
If you really need the guarantee and you only care about 10, you could create your own trait, for example: