I need to get index of macro repetition element to write next code:
struct A {
data: [i32; 3]
}
macro_rules! tst {
( $( $n:ident ),* ) => {
impl A {
$(
fn $n(self) -> i32 {
self.data[?] // here I need the index
}
)*
}
}
}
I know one way to do it: just tell user to write index by hands:
( $( $i:ident => $n:ident ),* )
But is there a more elegant way which does not require user's action?
The easiest way is to use recursion, like so:
struct A {
data: [i32; 3]
}
macro_rules! tst {
(@step $_idx:expr,) => {};
(@step $idx:expr, $head:ident, $($tail:ident,)*) => {
impl A {
fn $head(&self) -> i32 {
self.data[$idx]
}
}
tst!(@step $idx + 1usize, $($tail,)*);
};
($($n:ident),*) => {
tst!(@step 0usize, $($n,)*);
}
}
tst!(one, two, three);
fn main() {
let a = A { data: [10, 20, 30] };
println!("{:?}", (a.one(), a.two(), a.three()));
}
Note that I changed the method to take &self
instead of self
, since it made writing the example in the main
function easier. :)
Each step in the recursion just adds 1 to the index. It is a good idea to use "typed" integer literals to avoid compilation slowdown due to lots and lots of integer inference.