Enums 匹配宏中类似元组的枚举变量,其中枚举类型和变量是元变量:如何编写匹配模式?
简而言之,在Rust代码中,我尝试生成如下模式匹配: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 ) => {
如果让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