【问题标题】:Interpolate `ident` in string literal in `macro_rules!`在 `macro_rules!` 的字符串文字中插入 `ident`
【发布时间】:2022-07-19 21:42:00
【问题描述】:

是否可以将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 = 之后的实际字符串文字,而不仅仅是编译时字符串。

【问题讨论】:

    标签: rust rust-macros


    【解决方案1】:

    由于cfg 属性需要literalpub 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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • OP 知道并发布了它不起作用。
      猜你喜欢
      • 2021-11-23
      • 1970-01-01
      • 1970-01-01
      • 2014-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-04
      相关资源
      最近更新 更多