rust - 如何在匹配期间访问枚举变量的字段而不显式绑定(bind)它?

标签 rust

假设我有一个枚举 E ,这可能是自动生成的或在我的控制之外,有许多变体,每个变体都有许多字段。

enum E {
    A {
        x1: u8,
        x2: u8,
        x3: u8,
        // ...
        x9: u8,
    },
    B,
}

实际上,这些字段可能更长,而且不好记,也不好打字。

我现在想编写对 E 的(变体)进行操作的函数.不过我也懒,我不想重复自己,在解构枚举时明确声明每个使用的字段* .

直觉上我会期望绑定(bind)运算符 @在这里做这项工作,但它只绑定(bind)整个枚举 e ,而不是给定的变体 E::A .

实现以下意图的最短/最优雅的方式是什么?

fn f(e: &E) {
    match e {
        bad @ E::A { .. } => dbg!(bad.x1),
        _ => {}
    }
}

*更新 因为这已经在两个答案中提出了,所以我做 不是 想匹配 E::A { x1, .. } ,因为当需要多个具有长名称的字段时,这会变得乏味。在下面的示例中,我必须输入 some_other_field_with_an_impossibly_long_name在我自己的代码中两次(绑定(bind)一次,使用一次),而在假设的 bad @ E::A情况下,我只需要输入一次。

match e {
    E::A { some_field_with_a_long_name, some_other_field_with_an_impossibly_long_name, yet_another_field, .. } => dbg!(some_other_field_with_an_impossibly_long_name),
    _ => {}
}

最佳答案

您可以使用带有可变参数的宏,所以 编译器输入长名称两次,它绑定(bind)了您需要的参数。您可以在宏中调用您的函数而不是 println:

    f!(&e, x1);
    f!(&e, x2, x1);
macro_rules! f {
    ($e: expr, $( $name:ident ),+ ) => {
        match $e {
            E::A {   $($name),* , ..} => {
                println!("{:?}", &[$($name),*]); // call your function here.
            }
            _ => {}
        }
    };
}

Rust Playground 上试用

关于rust - 如何在匹配期间访问枚举变量的字段而不显式绑定(bind)它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59545450/

相关文章:

vector - 分割与Vec <u8>模式匹配的Vec <u8>

分配给静态变量时出现 Rust 'borrowed value does not live long enough'

mysql - 如何将 mysql::Conn 包含在lazy_static 宏中?

api - Reqwest 请求没有得到我的 reqwest::Client 的默认 header

rust - 如何找出可用的方法?

sockets - 如何在 Rust 中关闭 Unix 套接字?

rust - 元组结构构造函数提示私有(private)字段

opengl - 如何为 rust 设置VertexAttribPointer的偏移量?

vector - 如何拆箱包含在多态向量中的元素?

hashmap - 为什么 HashMap 需要加密安全的哈希函数?