【问题标题】:Is it possible for a macro to turn an identifier lowercase? [duplicate]宏是否可以将标识符变为小写? [复制]
【发布时间】:2019-02-10 15:43:41
【问题描述】:

是否可以在 Rust 宏中生成符号或标识符 从一个字符串?或者对标识符执行类似字符串的操作?

我想生成一个给定符号的方法,但需要将其小写为 获取方法名。

get!(B);

// should expand to

fn b() -> B {
    // method body
}

很容易接近...

macro_rules! get {
    ($kind:ident, $method:ident)
        =>
    {
        fn $method() -> $kind {
           // method body
        }
    }
}

get!(B, b)

但不满意。

【问题讨论】:

标签: macros rust


【解决方案1】:

我刚刚编写了一个程序宏 (casey) 来执行此操作。

#![feature(proc_macro_hygiene)]

use casey::lower;

lower!(B); // would render as `b`

更新

proc_macro_hygiene 自 rust 1.45.0 起稳定,因此不再需要 nightly。

【讨论】:

    【解决方案2】:

    前面的答案都是正确的;标准的声明性宏不能做到这一点,您可以改为使用过程宏。但是,dtolnay 的paste crate 是过程宏的更简单替代方案(特别是如果像我一样,这是您尚未深入研究的语言领域)。

    这些文档中的一个示例:

    use paste::paste;
    
    paste! {
        // Defines a const called `QRST`.
        const [<Q R S T>]: &str = "success!";
    }
    
    fn main() {
        assert_eq!(
            paste! { [<Q R S T>].len() },
            8,
        );
    }
    

    还支持大小写转换,例如[&lt;ld_ $reg:lower _expr&gt;]

    【讨论】:

      【解决方案3】:

      不,没有一个宏可以对标识符执行这种字符串操作。

      可以在编译器中创建这样的宏,但似乎不是一种流行的需求;今天只有实验性的concat_idents! 与此接近(即标识符的类似字符串的操作)。

      您的解决方法是目前唯一可用的解决方案。

      【讨论】:

      • 是的,我找到了concat_idents!,但这不是正确的。无论如何,谢谢,很高兴知道它不值得搜索。
      • 另外,concat_idents! 有很多缺点,这样的宏可能也会有。
      • dtolnay 的粘贴板条箱是现在执行此操作的好方法:crates.io/crates/paste
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多