如何在Rust宏中分离重复表达式中的最后一个表达式?
解决Rust宏中
$($f2:expr),+, $f3:expr的解析歧义问题 你遇到的歧义是因为Rust宏解析器无法区分$($f2:expr),+的末尾元素和后续的$f3:expr——由于表达式本身可以包含逗号(比如函数调用foo(1,2)),解析器无法确定哪里是f2的结束、f3的开始。
不用修改分隔符或交换参数顺序的话,可以通过拆分宏规则为**单个f2和多个f2**两种情况来解决:
macro_rules! macro1 { // 处理仅一个f2的场景 ($f1:expr, $f2:expr, $f3:expr) => { $f1(|a| { $f2(a, |b| { $f3(a, b); }); }); }; // 处理多个f2的场景 ($f1:expr, $first_f2:expr, $($rest_f2:expr),+, $f3:expr) => { $f1(|a| { // 处理第一个f2 $first_f2(a, |b| { $f3(a, b); }); // 处理剩余的f2 $( $rest_f2(a, |b| { $f3(a, b); }); )* }); }; }
原理说明
拆分规则后,宏解析器会优先匹配更具体的单个f2规则;当存在多个f2时,第二个规则会明确将第一个f2单独捕获,剩余的f2用$($rest_f2:expr),+匹配,最后固定捕获$f3:expr,彻底消除了解析歧义。
示例调用
两种场景的调用方式和你原本的写法完全一致:
// 单个f2的情况 macro1!( |callback| callback(42), |a, cb| cb(a + 1), |a, b| println!("a={}, b={}", a, b) ); // 多个f2的情况 macro1!( |callback| callback(42), |a, cb| cb(a + 1), |a, cb| cb(a * 2), |a, cb| cb(a - 3), |a, b| println!("a={}, b={}", a, b) );
内容的提问来源于stack exchange,提问作者user1002430
相关产品推荐
相关产品推荐

