Rust中如何用迭代器/向量调用可变参数宏iproduct?
如何用范围向量调用Itertools的iproduct!宏
iproduct!是Itertools包里的可变参数宏,能接受同类型的可变数量参数,常规用法如下(每个参数为Range类型):
use itertools::iproduct; // 遍历4×4×4网格的坐标,从(0, 0, 0)到(3, 3, 3) for (i, j, k) in iproduct!(0..4, 0..4, 0..4) { // 处理坐标逻辑 }
现在需要用一个范围向量来调用它,类似Python里product(*ranges)的动态传参效果,比如:
use std::ops::Range; let ranges : Vec<Range<i64>> = vec![ 5..10, 0..10, -2..3, ]; // 这里直接传向量给iproduct!会报错,该怎么正确调用? for (i, j, k) in iproduct!(ranges) { // 处理坐标逻辑 }
解决方法
iproduct!是编译时展开的宏,要求参数数量在编译期确定,而向量的长度是运行时动态的,所以直接传向量给宏行不通。这时可以用Itertools提供的multi_cartesian_product方法,它支持动态数量的迭代器输入,和iproduct!的功能一致:
use itertools::Itertools; use std::ops::Range; fn main() { let ranges: Vec<Range<i64>> = vec![ 5..10, 0..10, -2..3, ]; // 将向量转为迭代器的迭代器,调用multi_cartesian_product for coords in ranges.into_iter().multi_cartesian_product() { // coords是包含当前组合所有元素的Vec<i64> println!("组合:{:?}", coords); // 已知范围数量时,可通过切片解构为单独变量 if let [i, j, k] = coords.as_slice() { println!("i={}, j={}, k={}", i, j, k); } } }
注意事项
- 若需要元组形式的返回值,只能在编译期确定参数数量时使用
iproduct!宏,因为元组的长度是编译时固定的。 multi_cartesian_product返回的是Vec<T>类型的元素,通过切片解构或索引访问单个元素即可。
内容的提问来源于stack exchange,提问作者Rikard Olsson
相关产品推荐
相关产品推荐

