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

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

问题描述

在 Rust 中,有没有办法使用 traits 和 impls 来(递归地)展平元组?

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 你会遇到冲突的 trait 实现.

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天全站免登陆