I want to write generic functions of the form
fn my_function<T: num::Unsigned>(T: number) -> T
in order to use them for all unsigned integer types, so u8
-u128
.
However, often I want to do something like
let n = number + 1;
or
let mut n = number;
number -= 1;
in the function body. Now, everytime I use something like that, Rust tells me that the std::ops::SubAssign
-trait, the std::cmp::PartialOrd
-trait, etc. is not implemented for T
.
Is there an easy way to specify that my number is only one of the types u8
-u128
and hence enjoys all of those traits? And why isn't this clear to the Rust compiler, i.e. what would be an example for an Unsigned
-type that does not have the PartialOrd
-trait?
Edit: To clarify: What I would love is a way to say "T
has to have one of the types u8
...u128
(and maybe BigUInt
)" and then have Rust to automatically see "since T
is of one of those types, the following traits have to be implemented for T
: std::cmp::PartialOrd
, std::ops::SubAssign
, ..."
On the contrary, T: Unsigned
does imply T: One
. Unsigned
is a super trait over Num
which is a super trait over Zero
, One
, and more:
pub trait Unsigned: Num { }
pub trait Num: Zero + One + NumOps<Self, Self> + PartialEq<Self> { ... }
The key thing to understand is that 1
is not the same thing as T::one()
. This works for example:
use num::Unsigned; // 0.4.0
fn my_function<T: Unsigned>(number: T) -> T {
number + T::one()
}
The NumOps
trait means various arithmetic operators are defined, but only between T
s. The literal 1
may not be a T
, T
could be something like BigUint
.
What I would love is a way to say "
T
has to have one of the typesu8
...u128
(and maybeBigUInt
)" and then have Rust to automatically see "sinceT
is of one of those types, the following traits have to be implemented forT
:std::cmp::PartialOrd
,std::ops::SubAssign
, ..."
This is not how traits are designed to work. Traits can be implemented on foreign types, so even if Unsigned
is only implemented for those types now, some other crate my implement it for their types which don't have all the same properties of u8
...u128
, etc.
Instead, you should constrain T
to have the properties you need for the function to work. So you must be explicit.
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