llo*_*eta 6 tuples generic-programming rust
在 Rust 中,有没有办法使用traits 和impls 来(递归地)展平元组?
如果有帮助的话,可以使用 N 个嵌套对的东西是一个好的开始
trait FlattenTuple {
fn into_flattened(self) -> /* ??? */
}
// such that
assert_eq!((1, (2, 3)).into_flattened(), (1, 2, 3))
Run Code Online (Sandbox Code Playgroud)
如果可以扩展任何类型的嵌套元组的工作,那就更好了:
assert_eq!(((1, 2), 2, (3, (4, 5))).into_flattened(), (1, 2, 2, 3, 4, 5))
Run Code Online (Sandbox Code Playgroud)
也许对于“扁平化”的某些小定义来说,但实际上并非如此。
从最具体的实现开始:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
然后让它更通用一些:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
然后对每个可能的排列重复:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
这两个实现涵盖了您的两种情况。
但是,您必须枚举您想要的每种输入类型,可能是通过代码生成。我不知道如何“检查”输入类型,然后将其“拼接”到输出类型中。
您甚至可以尝试编写一些递归的东西:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
但这很快就会遇到基本情况问题:终端42不会实现FlattenTuple,如果你尝试这样做,impl<T> FlattenTuple for T你会遇到冲突的特征实现。
| 归档时间: |
|
| 查看次数: |
2957 次 |
| 最近记录: |