如何在 Rust 中迭代宏的参数?

8
我正在尝试创建一个宏,用于填充具有固定大小的向量的前几个元素。其余元素应为零。我写了以下代码:
const SIZE: usize = 3;

#[derive(Debug)]
struct MyVec {
    data: [f32; SIZE]
}

macro_rules! my_vec {
    ($($x:expr),*) => [{
        let mut data: [f32; SIZE] = [0.0; SIZE];
        for (i, e) in x.enumerate() {
            data[i] = e;
        }
        MyVec { data }
    }]
}

fn main() {
    let v = my_vec![1.0, 2.0];
    println!("{:?}", v);  // must be MyVec { data: [1.0, 2.0, 0.0] }
}

看起来我尝试以错误的方式迭代参数。我该怎么修复呢?

1个回答

11
你可以这样做。在$(...)*内部的代码将会为每个匹配项进行扩展。
const SIZE: usize = 3;

#[derive(Debug)]
struct MyVec {
    data: [f32; SIZE],
}

macro_rules! my_vec {
    ( $( $x:expr ),* ) => {
        {
            let mut data: [f32; SIZE] = [0.0; SIZE];
            let mut index = 0;
            $(
                #[allow(unused_assignments)]
                {
                    data[index] = $x;
                    index = index + 1;
                }
            )*
            MyVec { data }
        }
    };
}

fn main() {
    let v = my_vec![1.0, 2.0];
    println!("{:?}", v); // print MyVec { data: [1.0, 2.0, 0.0] }
}

谢谢,它起作用了。为什么在index = index + 1这一行会收到警告信息“warning: value assigned to 'index' is never read”? - Fomalhaut
1
@Fomalhaut 这将扩展为 let mut index = 0; data[index] = …; index = index + 1; data[index] = …; index = index + 1; data[index] = …; index = index + 1;,最后一个 index = index + 1 会产生警告。我已编辑答案以忽略该警告。 - mcarton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接