如何编写可转发含括号参数的Rust宏?现有代码报错求助
解决Rust宏转发复杂参数的问题
你的代码有两个关键问题导致报错,我们一步步来修复:
1. 笔误:错误调用函数而非宏
在parse宏的if分支里,你写了parse($then)——这里少了感叹号!,Rust会把它当成调用一个名为parse的普通函数,但你并没有定义这个函数。需要改成parse!($then)来正确调用宏。
2. parse宏缺少多指令匹配规则
你的forward宏会在转发的参数后追加; done,这会让parse宏收到类似if (done) {done}; done这样的多指令输入,但你的parse宏只能匹配单个done或者单个if结构,没有规则能处理分号分隔的多个指令序列。
我们需要给parse宏添加一个规则,用来处理这种多指令的情况:
修复后的完整代码
macro_rules! parse { // 匹配单独的done指令 (done) => { println!("done!"); }; // 匹配if结构 (if ($cond:tt) {$then:tt}) => { println!("if! "); parse!($cond); parse!($then); // 修正笔误,添加! }; // 匹配分号分隔的多个指令:先处理第一个,再递归处理剩余部分 ($first:tt; $($rest:tt)*) => { parse!($first); parse!($($rest)*); }; } macro_rules! forward { // 转发所有参数,并追加; done ($($e:tt)*) => (parse!($($e)*; done)); } fn main() { forward!(if (done) {done} ); }
代码解释
- 新增的
($first:tt; $($rest:tt)*)规则会匹配分号分隔的指令序列:它会先处理第一个指令$first,然后递归处理剩下的所有指令$($rest)*,完美适配forward宏追加的内容。 - 修正了
parse($then)为parse!($then),确保正确调用宏而非不存在的函数。
现在运行这段代码,会输出:
if! done! done! done!
完全符合预期:先处理if结构打印if!,递归处理cond(done)打印done!,再处理then(done)打印done!,最后处理forward追加的done再打印一次done!。
内容的提问来源于stack exchange,提问作者Mae Milano
相关产品推荐
相关产品推荐

