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

Lod*_*din 5 macros rust

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

struct A {
    data: [i32; 3]
}

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

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

( $( $i:ident => $n:ident ),* )
Run Code Online (Sandbox Code Playgroud)

但是,有没有一种更优雅的方式不需要用户采取行动呢?

DK.*_*DK. 6

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

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()));
}
Run Code Online (Sandbox Code Playgroud)

请注意,我将方法改为采用&self代替self,因为它使在main函数中编写示例更加容易。:)

递归的每个步骤仅将索引加1。最好使用“类型化”整数文字,以避免由于大量整数推断而导致的编译速度降低。