如何在宏中添加前缀/后缀标识符?
使用定义函数的宏时,是否可以向函数添加前缀?如何在宏中添加前缀/后缀标识符?
macro_rules! my_test {
($id:ident, $arg:expr) => {
#[test]
fn $id() {
my_test_impl(stringify!($id), $arg);
}
}
}
例如,fn my_test_$id() {
我使用其可以以数字开始的标识符定义的测试中,我想用一个共同的前缀。
[...]是否可以为函数添加前缀?
不,真的没有。 超级完全没有丝毫影响。
我想使用一个通用的前缀。
改为将它们全部放入mod
。
只是为了澄清,这是不可能的,因为[宏卫生](https://doc.rust-lang.org/book/macros.html#hygiene),这是一个功能,因为它是一个限制。 – allTwentyQuestions
@allTwentyQuestions:其实,这是一个比这更基本的限制。简短版本:为了使其工作,您必须能够在“标识符”位置使用宏。你不能。另一种方法是有某种明确的“令牌串联”*语法*。没有。卫生与它没有任何关系。 –
将它们放入模块中并不能解决将第一个字符作为数字的问题。 – ideasman42
目前稳定版不支持此功能。
但是还有一个特点,在夜间叫concat_idents
:
concat_idents!(my_test_, $id)
见
更新:似乎没有近期计划将其添加到稳定版本中,请参阅问题。
我没有提出'concat_idents!'的原因是,正如在该问题中提到的那样,*无用*。它不能修复;问题在于宏如何工作。 'concat_idents!'没有多少工作能够改善这种情况;宏系统将不得不更改为允许对AST节点进行急切的重新标记,或者编译器必须进行修改,以允许在任何地方使用宏名称(这会非常具有破坏性)。所以即使有这个问题有关的问题,它也不会是这个问题。这就是为什么我不打扰提及它。 –
即使只是注意到它可能/计划(但可能不会被支持),仍然值得提出来。 – ideasman42
如上所述,您应该使用这个子模块,但要记住,宏可以创建子模块,子模块可以被嵌套,允许他们的名字重叠,子模块可以提供impl
s,并且tests
子模块不是魔术。
我曾经提交过一个pull request,虽然#[no_mangle]
出口使它更难,但通过使用这些技巧重构代码避免了许多“锅炉板名称”。
来自@skade_:这是一个跟踪问题,讨论夜间功能'concat_idents',它允许。 https://github.com/rust-lang/rust/issues/29599 – ideasman42
另请参阅http://*.com/q/23061702/155423; http://*.com/q/24905160/155423; http://*.com/q/27415011/155423。 – Shepmaster