如何在Rust中创建具有常量值的枚举?

如何在Rust中创建具有常量值的枚举?,rust,Rust,我可以这样做: enum MyEnum { A(i32), B(i32), } 但不是这个: enum MyEnum { A(123), // 123 is a constant B(456), // 456 is a constant } 我可以用一个字段为A和B创建结构,然后实现该字段,但我认为可能有更简单的方法。有没有?回答这个问题的最佳方法是找出为什么要在枚举中使用常量:您是将一个值与每个变量相关联,还是希望每个变量都是该值(如C或C++中的enum)

我可以这样做:

enum MyEnum {
    A(i32),
    B(i32),
}
但不是这个:

enum MyEnum {
    A(123), // 123 is a constant
    B(456), // 456 is a constant
}

我可以用一个字段为
A
B
创建结构,然后实现该字段,但我认为可能有更简单的方法。有没有?

回答这个问题的最佳方法是找出为什么要在枚举中使用常量:您是将一个值与每个变量相关联,还是希望每个变量都是该值(如C或C++中的
enum

对于第一种情况,只保留枚举变量而不包含任何数据可能更有意义,并创建一个函数:

enum MyEnum {
    A,
    B,
}

impl MyEnum {
    fn value(&self) -> i32 {
        match *self {
            MyEnum::A => 123,
            MyEnum::B => 456,
        }
    }
}
// call like some_myenum_value.value()
这种方法可以多次应用,将许多单独的信息与每个变量关联起来,例如,您可能还需要一个
.name()->&'static str
方法。将来,这些函数甚至可以标记为
const
函数

对于第二种情况,可以指定显式整数标记值,就像C/C++:

enum MyEnum {
    A = 123,
    B = 456,
}

这可以通过所有相同的方式
match
ed启用,但也可以强制转换为整数
MyEnum::A作为i32
。(请注意,像
MyEnum::A | MyEnum::B这样的计算在Rust中并不自动合法:枚举有特定的值,它们不是位标志。)

看到这一点的人可能会偶然发现
FromPrimitive的引入和弃用。一个可能的替代品可能在这里也很有用。它允许您使用类似C的枚举,并使它们在数字和逻辑表示之间转换:

#[macro_use]
extern crate enum_primitive;
extern crate num;

use num::FromPrimitive;

enum_from_primitive! {
    #[derive(Debug, PartialEq)]
    enum FooBar {
        Foo = 17,
        Bar = 42,
        Baz,
    }
}

fn main() {
    assert_eq!(FooBar::from_i32(17), Some(FooBar::Foo));
    assert_eq!(FooBar::from_i32(42), Some(FooBar::Bar));
    assert_eq!(FooBar::from_i32(43), Some(FooBar::Baz));
    assert_eq!(FooBar::from_i32(91), None);
}
板条箱提供为枚举记录分配值的功能。此外,您可以将此宏与不同的值类型一起使用

use enum_map::{enum_map, Enum}; // 0.6.2

#[derive(Debug, Enum)]
enum Example {
    A,
    B,
    C,
}

fn main() {
    let mut map = enum_map! {
        Example::A => 1,
        Example::B => 2,
        Example::C => 3,
    };
    map[Example::C] = 4;

    assert_eq!(map[Example::A], 1);

    for (key, &value) in &map {
        println!("{:?} has {} as value.", key, value);
    }
}
创建具有常量值的“枚举”可以使用结构和进行扩充。 这类似于板条箱的工作原理及其产生的结果

此外,为了防止直接实例化MyEnum,您可以使用标记对其进行标记

#[非详尽]
髓鞘结构;
植入髓鞘{
发布常数A:i32=123;
发布常数B:i32=456;
}

然后,您只需像其他方式一样使用“enum”,通过访问
MyEnum::A
MyEnum::B

如何匹配值(在
value
函数中实现)?@MatejKormuth这已经晚了,但是,您只需匹配方法的返回值即可。假设枚举值存储在一个名为
some\u myenum\u value
的变量中,只需执行
匹配some\u myenum\u value.value(){…