enums - 在宏中匹配类似元组的枚举变量,其中枚举类型和变量是元变量: how do I write the matching pattern?

标签 enums rust macros pattern-matching

简而言之,在Rust代码中,我试图生成一个模式匹配,如下所示:

if let Foo::Variant(_) = value {}
//     ^^^^^^^^^^^^^^^
在宏中,同时将Foo(一种类型)和Variant(一种标识符)作为元变量传递给宏。在实际的用例中,我生成的是match而不是if let,并且正在使用同一枚举的多个变体,但是if let导致了一个较短的可重现示例。
这适用于简单的枚举:
enum Foo {
    Variant,
}

macro_rules! match_enum {
    (
        $value:ident: <$enum:ty>::$variant:ident
    ) => {
        if let <$enum>::$variant = $value {}
    };
}

fn main() {
    let foo = Foo::Variant;
    match_enum!(foo: <Foo>::Variant);
}
这样编译。
但是,当我使枚举变量类似于元组时,它会中断(更改突出显示):
enum Foo {
    Variant(usize),
//         ^^^^^^^
}

macro_rules! match_enum {
    (
        $value:ident: <$enum:ty>::$variant:ident
    ) => {
        if let <$enum>::$variant(_) = $value {}
//                              ^^^
    };
}

fn main() {
    let foo = Foo::Variant(0);
//                        ^^^
    match_enum!(foo: <Foo>::Variant);
}
   |         if let <$enum>::$variant(_) = $value {}
   |                -----------------^^^ unexpected `(` after qualified path
   |                |
   |                the qualified path
...
   |     match_enum!(foo: <Foo>::Variant);
   |     --------------------------------- in this macro invocation
我或多或少地尝试了一些变化;其中的$enum::$variant(_)<$enum::$variant>(_)<$enum::$variant>::(_)
这可能吗?我可能使用了错误类型的元变量吗?
This question似乎相关,但是它专注于混合单元和元组变体,尚未解决。

最佳答案

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

macro_rules! match_enum {
    (
        $value:ident: <$enum:ty>::$variant:ident
    ) => {
        // does not fix the problem
        if let <$enum>::Variant(_) = $value {}
        // fixes the problem
        if let Bar::$variant(_) = $value {}
    };
}
当问题发生在语法级别时,我们可以尝试更改所生成代码的语法结构,特别是通过引入类型别名。然后,我们需要限制该类型的范围,以免泄漏出宏:
macro_rules! match_enum {
    (
        $value:ident: <$enum:ty>::$variant:ident
    ) => {
        {
            type Enum = $enum;
            if let Enum::Variant(_) = $value {}
        }
    };
}
这只是一种解决方法,但足够干净。

关于enums - 在宏中匹配类似元组的枚举变量,其中枚举类型和变量是元变量: how do I write the matching pattern?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64146439/

相关文章:

c++ - 有没有办法在没有命名空间的情况下在 C++ 中嵌套枚举?

linux - OSX 上的应用程序不能生成超过 2048 个线程

c++ - 使用宏进行赋值和错误检查

c - 计算参数数量的宏

c# - 可以防止非位掩码字段上的意外按位运算符吗?

php - Laravel Eloquent - 按枚举字段排序

rust - 关于值(value)的rustc误报从未读过?

c++ - 当我尝试调用此自定义宏时,所有错误都会出现

MATLAB 枚举 switch 语句总是进入第一种情况

rust - "borrowed value does not live long enough"好像怪错了