Reputation: 297
I have an associated type MyType
.
This type is going to be an unsigned integer, but I use it because the size of the unsigned integer required for this variable is maybe going to change in the future. So MyType
is going to be one of: u32
, u64
, u128
.
So MyType will look like this when defined: MyType = u32
(of course it may not be u32
).
In my code, I need to increment this variable of type MyType
by one.
so I have to do this: let n: MyType = v + 1
, where v is the type of MyType
.
How can I do this, what trait restrictions should MyType
have?
I would want something like this: type MyType: UnsignedInt
, but the problem is there is no number trait in rust as far as I have seen.
Upvotes: 0
Views: 644
Reputation: 71025
The +
operator behavior is specified by the trait std::ops::Add
. This trait is generic over its output type, so if you want for example MyType
to have the semantics MyType + MyType = MyType
you can write:
trait MyTrait {
type MyType: std::ops::Add<Output = Self::MyType>;
}
All integers will implement this. If you need additional operators you can use the traits from std::ops
, but with multiple bounds this can become tedious. The crate num-traits
can help you with pre-declared traits that has all required ops and more. For example the trait NumOps
specify all arithmetic operators, and there are more traits such as Num
that includes equality and zero/one or PrimInt
that specifies basically every operation or method integers in Rust have.
Upvotes: 0
Reputation: 22601
Your description is very vague and it would be much easier if you added a code example, but deriving from the word associated type I tried to reconstruct a minimal example:
trait Incrementor {
type MyType;
fn increment(&self, value: Self::MyType) -> Self::MyType {
value + 1
}
}
struct U32Incrementor;
impl Incrementor for U32Incrementor {
type MyType = u32;
}
fn main() {
let incrementor = U32Incrementor;
println!("{}", incrementor.increment(10));
}
error[E0369]: cannot add `{integer}` to `<Self as Incrementor>::MyType`
--> src/main.rs:5:15
|
5 | value + 1
| ----- ^ - {integer}
| |
| <Self as Incrementor>::MyType
|
= note: the trait `std::ops::Add` is not implemented for `<Self as Incrementor>::MyType`
Is that about the problem you are having?
If yes, does this help?
use num_traits::{FromPrimitive, One, Unsigned};
trait Incrementor {
type MyType: Unsigned + FromPrimitive;
fn increment(&self, value: Self::MyType) -> Self::MyType {
value + Self::MyType::one()
}
fn increment_ten(&self, value: Self::MyType) -> Self::MyType {
value + Self::MyType::from_u8(10).unwrap()
}
}
struct U32Incrementor;
impl Incrementor for U32Incrementor {
type MyType = u32;
}
fn main() {
let incrementor = U32Incrementor;
println!("{}", incrementor.increment(10));
println!("{}", incrementor.increment_ten(10));
}
11
20
It's based on the excellent num_traits crate.
Upvotes: 2