【问题标题】:How to get index of macro repetition single element如何获取宏重复单个元素的索引
【发布时间】:2015-09-28 06:52:14
【问题描述】:

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

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 { one: i32, two: i32, three: i32 }
  • @ChrisMorgan。事实上,它与向量的实现有关,比如四元数,其中每种类型都有不同的长度并需要不同的访问器。我认为如果我对它们都使用一个代码,它可以简化工作。为什么你认为这是一个坏主意?
  • 我无法理解你实际上想用这个实现什么。你能分享一个完整的代码示例吗?
  • @ChrisMorgan,好吧,现在它只是一个概念,所以不存在我可以分享的真实代码。当(或如果)我按照我要求的方式编写它时,我可以在完成后分享它。

标签: macros rust


【解决方案1】:

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

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。使用“类型化”整数文字是一个好主意,以避免由于大量整数推断而导致编译速度变慢。

【讨论】:

  • 哇。惊人的。这让我大吃一惊。 Rust 仍然让我感到惊讶 :) 非常感谢,这是非常有趣的解决方案!
猜你喜欢
  • 2021-03-10
  • 1970-01-01
  • 2020-03-16
  • 1970-01-01
  • 1970-01-01
  • 2020-01-15
  • 2016-04-02
  • 2020-10-31
  • 1970-01-01
相关资源
最近更新 更多