Macros 在宏中构建枚举
是否可以使用定义为宏参数的字段在Rust宏中构建枚举?我试过这个:Macros 在宏中构建枚举,macros,rust,Macros,Rust,是否可以使用定义为宏参数的字段在Rust宏中构建枚举?我试过这个: macro_rules! build { ($($case:ty),*) => { enum Test { $($case),* } }; } fn main() { build!{ Foo(i32), Bar(i32, i32) }; } 但它失败,出现错误:预期标识,找到'Foo(i32) 请注意,如果字段是在枚举中定义的,则没有问题: macro_rules! build { ($($ca
macro_rules! build {
($($case:ty),*) => { enum Test { $($case),* } };
}
fn main() {
build!{ Foo(i32), Bar(i32, i32) };
}
但它失败,出现错误:预期标识,找到'Foo(i32)
请注意,如果字段是在枚举中定义的,则没有问题:
macro_rules! build {
($($case:ty),*) => { enum Test { Foo(i32), Bar(i32, i32) } };
}
fn main() {
build!{ Foo(i32), Bar(i32, i32) };
}
如果“我的宏”只接受简单字段,它也可以工作:
macro_rules! build {
($($case:ident),*) => { enum Test { $($case),* } };
}
fn main() {
build!{ Foo, Bar };
}
但在一般情况下,我无法让它工作。这是绝对可能的,但你把完全不相关的概念混为一谈了 类似于
$case:ty
的东西并不意味着$case
看起来像一种类型,它意味着$case
实际上是一种类型。枚举不是由一系列类型组成的;它们由一系列变体组成,这些变体是一个标识符,后跟(可选)元组结构体、记录结构体或标记值
解析器并不关心您给它的类型是否恰好看起来像一个有效的变量,它只是不需要类型,并且会拒绝在该位置解析一个类型
您需要的是使用类似于$case:variant
的东西。不幸的是,你不存在这样的匹配者。这样做的唯一方法是使用递归增量解析器手动解析它,这超出了so问题的范围,一点也不好笑。如果您想了解更多信息,请尝试将此作为起点
然而,您似乎并没有实际处理这些案例。你只是在盲目地替换它们。在这种情况下,您可以作弊,而不必费心尝试匹配任何连贯的内容:
macro\u规则!建造{
($($正文:tt)*)=>{
作为商品{
枚举测试{$($body)*}
}
};
}
宏规则!作为项目{
($i:项目)=>{$i};
}
fn main(){
建造!{Foo,Bar};
}
(顺便说一句,as_item!
这件事在(又称“重分析技巧”)一节中有解释。)
这只是获取作为build的输入提供的所有内容
,并将其推入枚举的主体中,而不关心它的外观
如果您试图对这些变体做一些有意义的事情,那么,您必须这样做,因为关于如何进行的最佳建议因答案而异。我们确实需要将Rust Macros小册子提升到官方文档级别,以使您的辛勤工作更容易找到!谢谢,我已经广泛使用了tlborm,但在本例中,我正在考虑可以在enum{}
中添加的内容(即enum{as_something!($($body)*)}
没有意识到需要将整个枚举包装成作为_项
。非常感谢tlborm,如果没有它,我就不会使用rust宏了。为什么这个示例在=>之后使用{}
,而所有TRPL书籍示例都使用
?