Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Rust, is there a way to iterate through the values of an enum?

I come from a Java background and I might have something like enum Direction { NORTH, SOUTH, EAST, WEST} and I could do something with each of the values in turn with the enhanced for loop like:

for(Direction dir : Direction.values())  {     //do something with dir } 

I would like to do a similar thing with Rust enums.

like image 595
dougli1sqrd Avatar asked Jan 27 '14 01:01

dougli1sqrd


People also ask

Can you iterate through enum?

Enums don't have methods for iteration, like forEach() or iterator(). Instead, we can use the array of the Enum values returned by the values() method.

How do you convert enum to string in Rust?

The easiest way to convert an enum to a String in Rust is to implement the std::fmt::Display trait. Then you can call the to_string() method.

What is the point of enums in Rust?

Additionally, creating a function that can take any type of Machine as its parameter is not possible using structs; in such a case, enums must be used. With an enum, the type of machine can be identified inside the function by using pattern matching with the match keyword.

How are enums stored in memory Rust?

All variants of an enum use the same amount of memory (in case of your Foo type, 16 bytes, at least on my machine). The size of the enum's values is determined by its largest variant ( One , in your example). Therefore, the values can be stored in the array directly.


2 Answers

You can use the strum crate to easily iterate through the values of an enum.

use strum::IntoEnumIterator; // 0.17.1 use strum_macros::EnumIter; // 0.17.1  #[derive(Debug, EnumIter)] enum Direction {     NORTH,     SOUTH,     EAST,     WEST, }  fn main() {     for direction in Direction::iter() {         println!("{:?}", direction);     } } 

Output:

NORTH SOUTH EAST WEST 
like image 133
Jordan Mack Avatar answered Sep 19 '22 19:09

Jordan Mack


If the enum is C-like (as in your example), then you can create a static array of each of the variants and return an iterator of references to them:

use self::Direction::*; use std::slice::Iter;  #[derive(Debug)] pub enum Direction {     North,     South,     East,     West, }  impl Direction {     pub fn iterator() -> Iter<'static, Direction> {         static DIRECTIONS: [Direction; 4] = [North, South, East, West];         DIRECTIONS.iter()     } }  fn main() {     for dir in Direction::iterator() {         println!("{:?}", dir);     } } 

If you make the enum implement Copy, you can use Iterator::copied and return impl Trait to have an iterator of values:

impl Direction {     pub fn iterator() -> impl Iterator<Item = Direction> {         [North, South, East, West].iter().copied()     } } 

See also:

  • What is the correct way to return an Iterator (or any other trait)?
  • Why can I return a reference to a local literal but not a variable?
like image 29
A.B. Avatar answered Sep 20 '22 19:09

A.B.