Search code examples
rusttraits

How to combine multiple traits as a "trait tuple"?


I write a lib like:

struct Foo<A: AppleTrait, B: BananaTrait, C: CarrotTrait> {...}

impl<A: AppleTrait, B: BananaTrait, C: CarrotTrait> Foo<A,B,C> {...}

struct Bar<A: AppleTrait, B: BananaTrait, C: CarrotTrait> {...}

impl<A: AppleTrait, B: BananaTrait, C: CarrotTrait> Bar<A,B,C> {...}

... and many more...

Notice that, things like <A: AppleTrait, B: BananaTrait, C: CarrotTrait> always come together, and has appeared many many times. So I want to eliminate such a burden.

Thus I hope I can do something like:

define_the_trait_alias ABCTrait = (A: AppleTrait, B: BananaTrait, C: CarrotTrait); // How to do this?

struct Foo<ABC: ABCTrait> {...}

impl<ABC: ABCTrait> Foo<ABC> {...}

Thanks!


Solution

  • Perhaps you can use associated types rather than generics. For example:

    trait AbcTrait {
        type Apple: AppleTrait;
        type Banana: BananaTrait;
        type Carrot: CarrotTrait;
    }
    
    struct Foo<Abc: AbcTrait> {
        abc: Abc,
    }
    impl<Abc: AbcTrait> Foo<Abc> {}
    
    struct Bar<Abc: AbcTrait> {
        abc: Abc,
    }
    impl<Abc: AbcTrait> Bar<Abc> {}
    

    When defining a concrete implementation of the trait, you get to choose which concrete type implements which associated type requested by the trait:

    impl AbcTrait for Salad {
        type Apple = GrannySmith;
        type Banana = Cavendish;
        type Carrot = LunarWhite;
    }