如何在 Rust 的宏中使用多个宏?

How to use multiple macros inside macros in Rust?

我想要一个代码来最终实现这一目标。

counters!(NAME1, “unit1”, NAME2, “unit2”)

// generates

const NAME1 = 0;
const NAME2 = 1;

static mut counters = [AtomicUsize::new(0), AtomicUsize::new(0)];

static units = [“unit1”, “unit2”]; 

到目前为止,我已经能够创建索引名称和任意值数组,但我在将它们组合在一起时遇到了麻烦。

playgound link

use std::sync::atomic::AtomicUsize;

macro_rules! gen_array {
    ($out:expr; ) => { $out };
    ([$($out:tt)*]; $name:ident, $($names:tt)*) => {
        gen_array!([$($out)* $name,]; $($names)*)
    };
}

macro_rules! gen_vars {
    ($cnt:expr; ) => {};
    ($cnt:expr; $name:ident, $($names:tt)*) => {
        const $name: usize = $cnt;
        gen_vars!($cnt + 1; $($names)*)
    };
}

macro_rules! counters {
    ($($name:ident),+) => {
        gen_vars!(0; $($name),+,);
        gen_array!([]; $($name),+,);
    };
}

fn main() {
    let arr = counters!(ONE, TWO);
    dbg!(arr);
}

这似乎是你想要的。

use std::sync::atomic::AtomicUsize;

macro_rules! gen_array {
    ($out:expr; ) => { $out };
    ([$($out:tt)*]; $name:literal, $($names:tt)*) => {
        gen_array!([$($out)* $name,]; $($names)*)
    };
}

macro_rules! gen_vars {
    ($cnt:expr; ) => {};
    ($cnt:expr; $name:ident, $($names:tt)*) => {
        const $name: usize = $cnt;
        gen_vars!($cnt + 1; $($names)*)
    };
}

macro_rules! counters {
    ($($name:ident,$value:literal),+) => {
        gen_vars!(0; $($name),+,);
        gen_array!([]; $($value),+,);
    };
}

fn main() {
    counters!(ONE, "unit1", TWO, "unit2");
}

Playground