如何获取宏重复单元素的索引

How to get index of macro repetition single element

我需要获取宏重复元素的索引来编写下一段代码:

struct A {
    data: [i32; 3]
}

macro_rules! tst {
    ( $( $n:ident ),* ) => {
        impl A {
            $(
                fn $n(self) -> i32 {
                    self.data[?] // here I need the index
                }
            ),*
        }
    }
}

我知道一种方法:告诉用户手写索引:

( $( $i:ident => $n:ident ),* )

但是有没有更优雅的不需要用户操作的方式呢?

最简单的方法是使用递归,如下所示:

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()));
}

请注意,我将方法更改为采用 &self 而不是 self,因为这样可以更轻松地在 main 函数中编写示例。 :)

递归中的每一步只是将索引加 1。最好使用 "typed" 整数文字来避免由于大量整数推断而导致编译速度变慢。