【问题标题】:Get enum discriminant without constructing an instance在不构造实例的情况下获取枚举判别式
【发布时间】:2020-10-18 03:52:57
【问题描述】:

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

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] 对应的判别向量进行检查。

【问题讨论】:

    标签: enums rust


    【解决方案1】:

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

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

    考虑到这一点以及您的预期用例,我会建议另一条路线。如果你想有一个东西的向量,看看元素是否匹配一个模式,并对数据做一些事情;您可以简单地使用匹配 slice pattern

    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
    }
    

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

    【讨论】:

    • 切片模式匹配简直太棒了。这是一种如此强大的语言。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-25
    • 2017-05-20
    • 2019-09-14
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    相关资源
    最近更新 更多