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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With