无需构造实例即可获得枚举判别式

Tho*_*eia 5 enums rust

我需要存储一个枚举判别式向量来进行比较:

use std::mem;

enum Thing {
    Foo(usize),
    Bar(usize, usize),
}

let ds: Vec<mem::Discriminant<Thing>> = vec![/* ??? */];

// ...

let thing: Thing = Foo(1234);

for d in ds.iter() {
    if mem::discriminant(thing) == d {
        println!("yay");
    }
}

Run Code Online (Sandbox Code Playgroud)

实际上,将使用宏来生成判别式列表,以便匹配枚举列表中的上下文。

例如,我们可能有这样的东西:

enum Thing {
    A(usize),
    B(f32),
    C(u8, u8, u8),
}

context_rule! {
    A(a) B(b) C(c) B(d) : a + b + c < d => C(b * c)
}
Run Code Online (Sandbox Code Playgroud)

vec![A, B, C, B]它应该生成一个对应于要检查的判别式的向量。

kmd*_*eko 6

我认为这个功能不存在。查看判别式 API 的 RFC ( 1 2 ),它是为相当小的用例而设计的。

当使用包含某些变体中的数据的 ADT 枚举时,有时需要了解变体但忽略数据,以便在数据不可散列或不重要时按变体比较两个值或将变体存储在哈希映射中。

考虑到这一点和您的预期用例,我会建议另一条路线。如果您想要一个向量,请查看元素是否与模式匹配,并对数据执行某些操作;您可以简单地使用带有切片模式的匹配。

enum Thing {
    A(usize),
    B(usize),
    C(usize, usize, usize),
}

fn main() {
    use Thing::*;

    let things = vec![A(0), B(1), C(2, 3, 4), B(5)];
    let result = match things.as_slice() {
        &[A(a), B(b), C(c, _, _), B(d)] if a + b + c < d => {
            C(b * c, 0, 0)
        }
        _ => todo!("add fallback")
    };

    // do something with result
}
Run Code Online (Sandbox Code Playgroud)

匹配臂看起来与您建议的宏非常相似。

  • 这种按切片进行的模式匹配简直令人惊叹。这是一种非常强大的语言。谢谢你! (2认同)