rust 在`macro_rules的字符串中插入`ident`!`

uyto3xhc  于 2023-08-05  发布在  Mac
关注(0)|答案(2)|浏览(138)

是否可以将ident类型的macro_rules!变量插入到宏中的字符串文字中?换句话说,是否可以“转义”文字的双引号?

// `trace_macros!` requires nightly
#![feature(trace_macros)]
trace_macros!(true);

macro_rules! export_mod_if_feature {
    ($system:ident) => {
        #[cfg(target_os = "$system")] // <-- problem is here
        pub mod $system;
    };
}

export_mod_if_feature!(linux);

// ... should translate to:
#[cfg(target_os = "linux")]
pub mod linux;

// ... but instead it becomes:
#[cfg(target_os = "$system")]
pub mod linux;

字符串
我试过使用#[cfg(target_os = stringify!($system))],但是cfg需要在target_os =之后有一个实际的字符串,而不仅仅是一个编译时字符串。

hs1ihplo

hs1ihplo1#

由于cfg属性需要一个literal,而pub mod需要一个ident,所以我认为可以使用两个值作为宏的输入,并将一个作为literal元变量,另一个作为ident元变量进行匹配。当功能和模块的名称不同时,这将更加灵活。

#![feature(trace_macros)]
trace_macros!(true);

macro_rules! export_mod_if_feature {
    ($system:literal, $module:ident) => {
        #[cfg(target_os = $system)]
        pub mod $module;
    };
}

export_mod_if_feature!("linux", linux);

字符串
Playground

8yoxcaq7

8yoxcaq72#

是的,stringify!(...)宏可以做到这一点,this thread也是如此。

相关问题