首页 > 解决方案 > 在编译时将对象添加到数组的宏?

问题描述

我想创建一个静态编译时生成的变量列表。也就是说,当程序启动时,它们已经存在,我不需要对其进行变异。

目前我正在这样做:

pub type ProfilerInfo = (&'static str, &'static str);

pub const Fps: ProfilerInfo = ("fps", "Frames Per Second");
pub const DecodingElapsed: ProfilerInfo = ("det", "Decoding Elapsed Time");
pub const DecodedPerSec: ProfilerInfo = ("dps", "Decoded Per Second");
pub const BytesPerSec: ProfilerInfo = ("bps", "Bytes Per Second");

pub const ALL_VARIABLES: &'static [&'static ProfilerInfo] = &[&Fps, &DecodingElapsed, &DecodedPerSec, &BytesPerSec];

但是这很容易出错,我可能会忘记在列表中添加变量之一ALL_VARIABLES

有没有办法创建一个创建ProfilerInfo并添加到的宏ALL_VARIABLES

背景:为什么我需要这个?好吧,这个列表是这样由命令行返回的my_program --list-variables,所以最好在应用程序启动时完成。

我认为不可能像我在顶部那样使用数组,但也许使用Vec?

标签: rust

解决方案


您需要一个为您创建ALL_VARIABLES静态切片的宏。

pub type ProfilerInfo = (&'static str, &'static str);

macro_rules! profiler_variables {
    ($(pub const $id:ident: ProfilerInfo = $rhs:expr;)*) => {
        $(
            pub const $id: ProfilerInfo = $rhs;
        )*
        pub const ALL_VARIABLES: &'static [&'static ProfilerInfo] = &[$(&$id),*];
    }
}

profiler_variables! {
    pub const Fps: ProfilerInfo = ("fps", "Frames Per Second");
    pub const DecodingElapsed: ProfilerInfo = ("det", "Decoding Elapsed Time");
    pub const DecodedPerSec: ProfilerInfo = ("dps", "Decoded Per Second");
    pub const BytesPerSec: ProfilerInfo = ("bps", "Bytes Per Second");
}

fn main() {
    for (name, descr) in ALL_VARIABLES.iter() {
        println!("Variable: {}, description: {}", name, descr)
    }
}

输出:

Variable: fps, description: Frames Per Second
Variable: det, description: Decoding Elapsed Time
Variable: dps, description: Decoded Per Second
Variable: bps, description: Bytes Per Second

操场


推荐阅读