Enums 匹配宏中类似元组的枚举变量,其中枚举类型和变量是元变量:如何编写匹配模式?

Enums 匹配宏中类似元组的枚举变量,其中枚举类型和变量是元变量:如何编写匹配模式?,enums,rust,macros,pattern-matching,Enums,Rust,Macros,Pattern Matching,简而言之,在Rust代码中,我尝试生成如下模式匹配: 如果让Foo::Variant()=value{} // ^^^^^^^^^^^^^^^ 在宏中,将Foo(类型)和Variant(标识符)作为元变量传递给宏。在实际用例中,我生成了一个match而不是if-let,并且使用了同一枚举的多个变量,但是if-let导致了一个更短的可复制示例 这适用于简单枚举: enum Foo{ 变体, } 宏规则!匹配枚举{ ( $value:ident::$variant:ident ) => {

简而言之,在Rust代码中,我尝试生成如下模式匹配:

如果让Foo::Variant()=value{}
//     ^^^^^^^^^^^^^^^
在宏中,将
Foo
(类型)和
Variant
(标识符)作为元变量传递给宏。在实际用例中,我生成了一个
match
而不是
if-let
,并且使用了同一枚举的多个变量,但是
if-let
导致了一个更短的可复制示例

这适用于简单枚举:

enum Foo{
变体,
}
宏规则!匹配枚举{
(
$value:ident::$variant:ident
) => {
如果let::$variant=$value{}
};
}
fn main(){
让foo=foo::Variant;
匹配枚举!(foo:::变量);
}
这是一份汇编

但是,当我将枚举变量元组设置为类似时,它会中断(突出显示更改):

enum Foo{
变体(usize),
//         ^^^^^^^
}
宏规则!匹配枚举{
(
$value:ident::$variant:ident
) => {
如果let::$variant()=$value{}
//                              ^^^
};
}
fn main(){
设foo=foo::Variant(0);
//                        ^^^
匹配枚举!(foo:::变量);
}
|如果let::$variant()=$value{}
|----------------^^^意外的“(`在限定路径之后
|                |
|限定路径
...
|匹配枚举!(foo:::变量);
|-------------------------------------在此宏调用中
我尝试了一些变体,或多或少是盲目的;
$enum::$variant()
()
::()

这可能吗?我是否使用了错误类型的元变量


似乎是相关的,但它侧重于混合单元和元组变量,尚未解决。

该问题似乎是由
$enum
元变量引起的,如下轻微修改所示:

宏\u规则!匹配\u枚举{
(
$value:ident::$variant:ident
) => {
//没有解决问题
如果let::Variant()=$value{}
//解决了这个问题
if let Bar::$variant()=$value{}
};
}
由于问题发生在语法级别,我们可以尝试更改生成代码的语法组成,特别是通过引入类型别名。然后,我们需要确定该类型的范围,以避免泄漏到宏中:

宏\u规则!匹配\u枚举{
(
$value:ident::$variant:ident
) => {
{
类型Enum=$Enum;
如果让Enum::Variant()=$value{}
}
};
}

这只是一个解决方法,但已经足够干净了。

问题似乎是由
$enum
元变量引起的,如下所示:

宏\u规则!匹配\u枚举{
(
$value:ident::$variant:ident
) => {
//没有解决问题
如果let::Variant()=$value{}
//解决了这个问题
if let Bar::$variant()=$value{}
};
}
由于问题发生在语法级别,我们可以尝试更改生成代码的语法组成,特别是通过引入类型别名。然后,我们需要确定该类型的范围,以避免泄漏到宏中:

宏\u规则!匹配\u枚举{
(
$value:ident::$variant:ident
) => {
{
类型Enum=$Enum;
如果让Enum::Variant()=$value{}
}
};
}
这只是一个解决办法,但已经足够干净了

   |         if let <$enum>::$variant(_) = $value {}
   |                -----------------^^^ unexpected `(` after qualified path
   |                |
   |                the qualified path
...
   |     match_enum!(foo: <Foo>::Variant);
   |     --------------------------------- in this macro invocation