Reputation: 9825
I am trying to create a macro that fills first elements of a vector with a fixed size. The rest of elements should be zero. I wrote:
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] }
}
It looks like I try to iterate the arguments in a wrong way. How can I fix it?
Upvotes: 9
Views: 5260
Reputation: 24974
You could do this. The code inside the $(...)*
will be expanded for each matches.
const SIZE: usize = 3;
#[derive(Debug)]
#[allow(dead_code)]
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] }
}
Upvotes: 12