注意:我不确定您是否应该这样做,但无论如何这里有一个方法。 (我觉得很hacky,这可能是因为我不知道如何制作更好的宏。)
同构元组(T, T)
你描述的方式:
impl<T> Foo for (T, T) where T: Foo
这里,整个元组必须是同质的(即(MyType, MyType2).do_something()将不工作,因为单态化)。
这会引发一个标志,因为元组用于异构数据。
如果只实现一个同构元组的特征仍然是您想要的,我们可以通过the standard library does to implement traits for varied length tuples 的方式实现一个宏,并进行一些修改。 (点击impl右侧的src查看其来源。)
macro_rules! replace_expr {
($_t:tt $sub:ty) => {$sub};
}
macro_rules! tuple_impls {
( $( $name:ident )+ ) => {
impl<T: Foo> Foo for ($(replace_expr!(($name) T),)+)
{
fn do_something(self) -> Self {
let ($($name,)+) = self;
($($name.do_something(),)+)
}
}
};
}
tuple_impls! { A }
tuple_impls! { A B }
tuple_impls! { A B C }
tuple_impls! { A B C D }
tuple_impls! { A B C D E }
tuple_impls! { A B C D E F }
tuple_impls! { A B C D E F G }
tuple_impls! { A B C D E F G H }
tuple_impls! { A B C D E F G H I }
tuple_impls! { A B C D E F G H I J }
tuple_impls! { A B C D E F G H I J K }
tuple_impls! { A B C D E F G H I J K L }
Playground
异构元组(T1, T2)
如果你对 (MyType, MyType2).do_something() 工作没问题(两者都实现了 Foo 特征),你可以试试这个更简单的宏:
macro_rules! tuple_impls {
( $( $name:ident )+ ) => {
impl<$($name: Foo),+> Foo for ($($name,)+)
{
fn do_something(self) -> Self {
let ($($name,)+) = self;
($($name.do_something(),)+)
}
}
};
}
tuple_impls! { A }
tuple_impls! { A B }
tuple_impls! { A B C }
tuple_impls! { A B C D }
tuple_impls! { A B C D E }
tuple_impls! { A B C D E F }
tuple_impls! { A B C D E F G }
tuple_impls! { A B C D E F G H }
tuple_impls! { A B C D E F G H I }
tuple_impls! { A B C D E F G H I J }
tuple_impls! { A B C D E F G H I J K }
tuple_impls! { A B C D E F G H I J K L }
Playground