宏分析器中沒有「回溯」,所以不可以直接使用$($head:tt)* $tail:tt
。但是你可以通過自己逆轉來實現。
macro_rules! concat_reverse {
([] $($reversed:tt)*) => {
concat!($(stringify!($reversed)),*) // base case
};
([$first:tt $($rest:tt)*] $($reversed:tt)*) => {
concat_reverse!([$($rest)*] $first $($reversed)*) // recursion
};
}
fn main() {
println!("{}", concat_reverse!([e d c b a]))
// output: abcde
}
宏跡的樣子:
concat_reverse!([e d c b a])
== concat_reverse!([d c b a] e)
== concat_reverse!([c b a] d e)
== concat_reverse!([b a] c d e)
== concat_reverse!([a] b c d e)
== concat_reverse!([] a b c d e)
== concat!(stringify!(a), stringify!(b), stringify!(c), stringify!(d), stringify!(e))
你可以做一些「地圖」和「減少」的操作(例如,用於計數)在遞歸階段。
請注意,這種方法會吃掉你的遞歸深度,你可能需要提高你的#![recursion_limit="..."]
。
謝謝你完美的作品,用它來回答我自己的問題:http://stackoverflow.com/a/42176533/432509。 'apply_args_reverse'宏可能對別人有用,因爲它允許顛倒現有宏的參數。 – ideasman42