You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写可转发含括号参数的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:26:04