Is it possible to automatically implement a trait for any tuple that is made up of types that all implement the trait?

拈花ヽ惹草 提交于 2019-11-28 10:45:39

问题


Suppose that I have a

trait Happy {}

I can implement Happy for whatever struct I might want, for example:

struct Dog;
struct Cat;
struct Alligator;

impl Happy for Dog {}
impl Happy for Cat {}
impl Happy for Alligator {}

Now, I would like to automatically impl my Happy trait for whatever tuple is made up of types that all implement the Happy trait. Intuitively, a tuple of all happy is happy as well.

Is it possible to do such a thing? For example, I can trivially extend the implementation of Happy to whatever tuple of two Happy types:

impl <T, Q> Happy for (T, Q) where T: Happy, Q: Happy {}

As a result, this compiles perfectly:

fn f(_: impl Happy) {
}

fn main() {
    f((Dog{}, Alligator{}));
}

But how could I generalize that to any tuple, of any length? As far as my understanding goes, we don't have variadic generics in Rust. Is there a workaround?


回答1:


we don't have variadic generics in Rust.

Correct.

Is there a workaround?

You use a macro:

trait Happy {}

macro_rules! tuple_impls {
    ( $head:ident, $( $tail:ident, )* ) => {
        impl<$head, $( $tail ),*> Happy for ($head, $( $tail ),*)
        where
            $head: Happy,
            $( $tail: Happy ),*
        {
            // interesting delegation here, as needed
        }

        tuple_impls!($( $tail, )*);
    };

    () => {};
}

tuple_impls!(A, B, C, D, E, F, G, H, I, J,);

This now compiles:

fn example<T: Happy>() {}

fn call<A: Happy, B: Happy>() {
    example::<(A, B)>();
} 

This isn't generally seen as a big problem because long tuples are basically unreadable and you can always nest tuples if really needed.

See also:

  • Automatically implement traits of enclosed type for Rust newtypes (tuple structs with one field)
  • How to iterate or map over tuples?


来源:https://stackoverflow.com/questions/55553281/is-it-possible-to-automatically-implement-a-trait-for-any-tuple-that-is-made-up

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!