如何在Rust宏中为多个参数编写嵌套循环?
问题描述
现有如下Rust宏代码:
macro_rules! test { ( $( $x1:expr ),*; blub $( $x2:expr ),* ) => { $( println!("{} * {} = {}", $x1, $x2, $x1 * $x2); )* } } fn main() { test!{1, 2, 3; blub 4, 5, 6}; }
运行后输出为:
1 * 4 = 4 2 * 5 = 10 3 * 6 = 18
但期望实现嵌套遍历的效果,即让第一个序列的每个元素依次和第二个序列的所有元素配对,输出应为:
1 * 4 = 4 1 * 5 = 5 1 * 6 = 6 2 * 4 = 8 2 * 5 = 10 2 * 6 = 12 3 * 4 = 12 3 * 5 = 15 3 * 6 = 18
解决方案
要实现嵌套遍历,需要在宏中使用双层重复捕获,外层遍历第一个序列的每个元素,内层对每个元素再遍历第二个序列的所有元素。修改后的宏代码如下:
macro_rules! test { ( $( $x1:expr ),*; blub $( $x2:expr ),* ) => { $( $( println!("{} * {} = {}", $x1, $x2, $x1 * $x2); )* )* } } fn main() { test!{1, 2, 3; blub 4, 5, 6}; }
逻辑说明
原宏里的$( ... )*只会将两个序列并行展开(第一个序列的第n个元素对应第二个序列的第n个元素)。而修改后的双层$( $( ... )* )*,会先遍历第一个序列的每个$x1,对每个$x1再完整遍历第二个序列的所有$x2,从而生成所有元素的配对组合,达到嵌套循环的效果。
内容的提问来源于stack exchange,提问作者Michael Mahn
相关产品推荐
相关产品推荐

