我希望编写一个Rust宏,它将整个参数转发给第二个宏 - 即使该参数包含令人兴奋的括号。
这是我到目前为止所尝试的内容:
macro_rules! parse {
(done) => (println!("done!"));
(if ($cond:tt) {$then:tt}) => (println!("if! "); parse!($cond); parse($then));
}
macro_rules! forward {
($($e:tt)*) => (parse!($($e)*; done));
}
fn main() {
forward!(if (done) {done} );
}
这不起作用,并产生错误:
error: no rules expected the token `if`
我在这里做错了什么?
编辑:除了简单地将参数转发给forward
之外,我希望能够"粘贴"标记; done
到forward
的参数末尾。有没有办法在保留这种行为的同时完成这项工作?
答案 0 :(得分:3)
问题是; done
中的forward
。这里发生的是宏扩展代码一次一个地匹配文字输入令牌。如果一只手臂没有匹配,它会放弃并尝试下一只手臂。当它用完手臂试试时,它必须失败并解释原因。
但输入中的哪个令牌是问题?当有可能涉及多个武器的时候回答是很难的,所以相反它只是挑选第一个令牌并说'#34;这就是问题"。
每当你看到一个宏扩展抱怨输入中的第一个令牌不匹配时,它很可能会在输入中的某些东西中绊倒它。
修复该问题(以及修复错过其parse
的{{1}}次调用)会产生:
!