如何递归采用宏的最后一个参数? [英] How to recursively take the last argument of a macro?
问题描述
使用一个简单的递归宏,如下面的示例,它的共同点是第一个参数,然后遍历其余参数.
Using a simple recursive macro like the example below, its common to take the first argument, then glob the rest.
macro_rules! count_tts {
() => {0usize};
($_head:tt $($tail:tt)*) => {1usize + count_tts!($($tail)*)};
}
有没有一种方法可以递归地接受最后一个参数?
Is there a way to recursively take the last argument?
这使得可以:
- 反向处理参数.
- 考虑所有先前的参数(例如,将其计数为查看相关问题)
类似($($head:tt)* $tail:tt)
的东西,但这不起作用.
Something like ($($head:tt)* $tail:tt)
... but this doesn't work.
推荐答案
宏解析器中没有回溯"功能,所以不能使用$($head:tt)* $tail:tt
直接执行此操作.但是您可以自己反转.
There is no "backtracking" in the macro parser, so no you can't do this directly with $($head:tt)* $tail:tt
. But you can do it by reversing it yourself.
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))
您可以在递归阶段执行一些映射"和减少"操作(例如,用于计数).
You could do some "map" and "reduce" operation (e.g. for counting) in the recursion phase.
请注意,此方法会影响您的递归深度,您可能需要提高#![recursion_limit="..."]
.
Note that this method will eat your recursion depth, you may need to raise your #![recursion_limit="..."]
.
这篇关于如何递归采用宏的最后一个参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!