使用一个简单的递归宏,如下面的例子所示,它常见于第一个参数,然后是其余的。
macro_rules! count_tts {
() => {0usize};
($_head:tt $($tail:tt)*) => {1usize + count_tts!($($tail)*)};
}
有没有办法以递归方式取最后一个参数?
这使得:
成为可能类似于($($head:tt)* $tail:tt)
......但这不起作用。
答案 0 :(得分:2)
宏解析器中没有“回溯”,因此不能直接使用$($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))
你可以在递归阶段做一些“map”和“reduce”操作(例如用于计数)。
请注意,此方法会占用您的递归深度,您可能需要提升#![recursion_limit="..."]
。