有什么方法可以递归地使元组变平? [英] Are there any ways to recursively flatten tuples?

查看:66
本文介绍了有什么方法可以递归地使元组变平?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Rust中,有什么方法可以使用 trait s和 impl s(递归)展平元组吗?

In Rust, is there any way to use traits and impls to (recursively) flatten tuples?

如果有帮助,那么可以使用N个嵌套对的东西是一个很好的开始

If it helps, something that works with N nested pairs is a good start

trait FlattenTuple {
    fn into_flattened(self) -> /* ??? */
}

// such that
assert_eq!((1, (2, 3)).into_flattened(), (1, 2, 3))

如果可以使用任何类型的嵌套元组扩展工作,那就更好了:

It would be even better if it could be extended work with any kind of nested tuple such that:

assert_eq!(((1, 2), 2, (3, (4, 5))).into_flattened(), (1, 2, 2, 3, 4, 5))

推荐答案

也许对于扁平化"的某些小定义,但实际上并非如此.

Maybe for certain small definitions of "flatten", but realistically not really.

从最具体的实施开始:

trait FlattenTuple {
    fn into_flattened(self) -> (u8, u8, u8);
}

impl FlattenTuple for (u8, (u8, u8)) {
    fn into_flattened(self) -> (u8, u8, u8) {
        (self.0, (self.1).0, (self.1).1)
    }
}

然后使它更通用:

trait FlattenTuple {
    type Output;
    fn into_flattened(self) -> Self::Output;
}

impl<A, B, C> FlattenTuple for (A, (B, C)) {
    type Output = (A, B, C);

    fn into_flattened(self) -> Self::Output {
        (self.0, (self.1).0, (self.1).1)
    }
}

然后对每个可能的排列重复:

impl<A, B, C, D, E, F> FlattenTuple for ((A, B), C, (D, (E, F))) {
    type Output = (A, B, C, D, E, F);

    fn into_flattened(self) -> Self::Output {
        ((self.0).0, (self.0).1, self.1, (self.2).0, ((self.2).1).0, ((self.2).1).1)
    }
}

这两个实现涵盖了您的两种情况.

These two implementations cover your two cases.

但是,您可能必须通过代码生成来枚举所需的每种输入类型.我没有办法检查"输入类型,然后将其拼接"为输出类型.

However, you'd then have to enumerate every input type you'd like, probably via code generation. There's no way I'm aware of to "inspect" the input type and then "splice" it into the output type.

您甚至可以尝试编写一些递归的内容:

You can even try to write something somewhat recursive:

impl<A, B, C, D, E, F> FlattenTuple for (A, B)
    where A: FlattenTuple<Output = (C, D)>,
          B: FlattenTuple<Output = (E, F)>,
{
    type Output = (C, D, E, F);

    fn into_flattened(self) -> Self::Output {
        let (a, b) = self;
        let (c, d) = a.into_flattened();
        let (e, f) = b.into_flattened();

        (c, d, e, f)
    }
}

但这会很快遇到基本情况:终端 42 不实现 FlattenTuple ,并且如果您尝试 impl< T> ;,FlattenTuple for T ,您将遇到冲突的特征实现.

But this will quickly run into base-case issues: the terminal 42 doesn't implement FlattenTuple, and if you try to impl<T> FlattenTuple for T you will hit conflicting trait implementations.

这篇关于有什么方法可以递归地使元组变平?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆