Consider the following code with a struct S
with a constrained generic type parameter Idx
and a default value for Idx
.
use num::{PrimInt, Unsigned};
struct S<Idx = u32>
where
Idx: Unsigned PrimInt, {
// ... Some fields
}
impl<Idx: Unsigned PrimInt> Clone for S<Idx> {
fn clone(&self) -> Self {
S {}
}
}
impl<Idx: Unsigned PrimInt> Eq for S<Idx> {
fn eq(&self, rhs: &Self) -> bool {
true
}
}
I would like to implement a bunch of traits for S
, but I find always specifying the constraints for the Idx
type parameter tedious. If I don't specify Idx
on a trait implementation, the code compiles but only has an implementation for Idx = u32
.
Is there some convenience syntax where I don't have to specify the Idx: Unsigned PrimInt
all the time but still correctly implements the traits?
CodePudding user response:
There isn't a syntax built in, but you can make one yourself using macros:
macro_rules! s_impl {
( $($t:path => $i:tt) ) => {
$(impl<Idx: Unsigned PrimInt> $t for S<Idx> $i)
}
}
Then you can do:
s_impl!(
Clone => {
fn clone(&self) -> Self {
S {}
}
}
PartialEq => {
fn eq(&self, rhs: &Self) -> bool {
true
}
}
);
CodePudding user response:
The answer from @cdhowie is correct, but I would like to point that there is an accepted (but not yet implemented, as of time of writing) RFC to allow you to omit such bounds - RFC #2089 Implied Bounds.
It is not yet clear what will be the form of the feature, though, because it is a semver hazard.