如何在宏中添加前缀/后缀标识符?

如何在宏中添加前缀/后缀标识符?

问题描述:

使用定义函数的宏时,是否可以向函数添加前缀?如何在宏中添加前缀/后缀标识符?

macro_rules! my_test { 
    ($id:ident, $arg:expr) => { 
     #[test] 
     fn $id() { 
      my_test_impl(stringify!($id), $arg); 
     } 
    } 
} 

例如,fn my_test_$id() {

我使用其可以以数字开始的标识符定义的测试中,我想用一个共同的前缀。

+1

来自@skade_:这是一个跟踪问题,讨论夜间功能'concat_idents',它允许。 https://github.com/rust-lang/rust/issues/29599 – ideasman42

+0

另请参阅http://*.com/q/23061702/155423; http://*.com/q/24905160/155423; http://*.com/q/27415011/155423。 – Shepmaster

[...]是否可以为函数添加前缀?

不,真的没有。 超级完全没有丝毫影响。

我想使用一个通用的前缀。

改为将它们全部放入mod

+1

只是为了澄清,这是不可能的,因为[宏卫生](https://doc.rust-lang.org/book/macros.html#hygiene),这是一个功能,因为它是一个限制。 – allTwentyQuestions

+3

@allTwentyQuestions:其实,这是一个比这更基本的限制。简短版本:为了使其工作,您必须能够在“标识符”位置使用宏。你不能。另一种方法是有某种明确的“令牌串联”*语法*。没有。卫生与它没有任何关系。 –

+0

将它们放入模块中并不能解决将第一个字符作为数字的问题。 – ideasman42

目前稳定版不支持此功能。


但是还有一个特点,在夜间叫concat_idents

concat_idents!(my_test_, $id) 

更新:似乎没有近期计划将其添加到稳定版本中,请参阅问题。

+0

我没有提出'concat_idents!'的原因是,正如在该问题中提到的那样,*无用*。它不能修复;问题在于宏如何工作。 'concat_idents!'没有多少工作能够改善这种情况;宏系统将不得不更改为允许对AST节点进行急切的重新标记,或者编译器必须进行修改,以允许在任何地方使用宏名称(这会非常具有破坏性)。所以即使有这个问题有关的问题,它也不会是这个问题。这就是为什么我不打扰提及它。 –

+0

即使只是注意到它可能/计划(但可能不会被支持),仍然值得提出来。 – ideasman42

如上所述,您应该使用这个子模块,但要记住,宏可以创建子模块,子模块可以被嵌套,允许他们的名字重叠,子模块可以提供impl s,并且tests子模块不是魔术。

我曾经提交过一个pull request,虽然#[no_mangle]出口使它更难,但通过使用这些技巧重构代码避免了许多“锅炉板名称”。