首页 > 解决方案 > 在不构造实例的情况下获取枚举判别式

问题描述

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

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");
    }
}

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

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

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)
}

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

标签: enumsrust

解决方案


我不认为这个功能存在。查看判别 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
}

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


推荐阅读