简体   繁体   中英

Rust: Convenience syntax for specifying types on trait implementations?

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?

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
        }
    }
);

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM