Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create enums with constant values in Rust?

Tags:

rust

I can do this:

enum MyEnum {     A(i32),     B(i32), } 

but not this:

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

I can create the structures for A and B with a single field and then implement that field, but I think there might be an easier way. Is there any?

like image 279
Incerteza Avatar asked Apr 29 '16 02:04

Incerteza


People also ask

How do I make a constant enum?

You can create an enum object using the enum keyword. Enum constants appear as a comma-separated list within a pair of curly brackets. An enum, which is short for enumeration, is a data type that has a fixed set of possible values.

Can we add constants to enum?

Enum contastants are static and final by default and cannot be changed after once it is created. Also Enums can be used in Switch statements like int and char data types. We can define values for enum constants at the time of creation, but then we must add a constructor and a field variable for this enum.

Can enums have the same value?

1. Two enum names can have same value. For example, in the following C program both 'Failed' and 'Freezed' have same value 0.

How do you create an enum in Rust?

To declare an enumeration, we write the enum keyword, followed by a unique name and a code block. Inside the code block we declare our actual words that will map to numbers, separated by commas. Enums in Rust are conventionally written with pascal case.


2 Answers

Creating an "enum" with constant values, can be augmented using structs and associated constants. This is similar to how crates like bitflags works and what it would generate.

Additionally, to prevent direct instantiation of MyEnum you can tag it with #[non_exhaustive].

#[non_exhaustive] struct MyEnum;  impl MyEnum {     pub const A: i32 = 123;     pub const B: i32 = 456; } 

Then you simply use the "enum" as you otherwise would, by accessing MyEnum::A and MyEnum::B.

like image 30
vallentin Avatar answered Oct 02 '22 14:10

vallentin


The best way to answer this is working out why you want constants in an enum: are you associating a value with each variant, or do you want each variant to be that value (like an enum in C or C++)?

For the first case, it probably makes more sense to just leave the enum variants with no data, and make a function:

enum MyEnum {     A,     B, }  impl MyEnum {     fn value(&self) -> i32 {         match *self {             MyEnum::A => 123,             MyEnum::B => 456,         }     } } // call like some_myenum_value.value() 

This approach can be applied many times, to associate many separate pieces of information with each variant, e.g. maybe you want a .name() -> &'static str method too. In the future, these functions can even be marked as const functions.

For the second case, you can assign explicit integer tag values, just like C/C++:

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

This can be matched on in all the same ways, but can also be cast to an integer MyEnum::A as i32. (Note that computations like MyEnum::A | MyEnum::B are not automatically legal in Rust: enums have specific values, they're not bit-flags.)

like image 173
huon Avatar answered Oct 02 '22 16:10

huon