How to "switch" through listing options?

I would like to write a function that toggles / switches the provided value to the following in the listing and wraps at the end:

enum Direction { NORTH, SOUTH, EAST, WEST } 

For example, NORTH => SOUTH , SOUTH => EAST , EAST => WEST , WEST => NORTH .

Is there an easier way than manually creating a static array, as described in Rust, is there a way to iterate over enum values?

 use Direction::*; static DIRECTIONS: [Direction; 4] = [NORTH, SOUTH, EAST, WEST]; 

Are enumerations not "enumerated"? I vaguely remember how I saw an example in Rust before, but I can not find it. Since Rust enums are more like unions / options, I assume this complicates the situation.

+5
source share
3 answers

I think something like this will do the trick:

 #[macro_use] extern crate num_derive; extern crate num_traits; use num_traits::FromPrimitive; #[derive(Debug, Copy, Clone, FromPrimitive)] enum Direction { NORTH = 0, SOUTH, EAST, WEST, } fn turn(d: Direction) -> Direction { FromPrimitive::from_u8((d as u8 + 1) % 4).unwrap() } fn main() { use Direction::*; for &d in [NORTH, SOUTH, EAST, WEST].iter() { println!("{:?} -> {:?}", d, turn(d)); } } 

This does not require unsafe , since it uses the automatically received FromPrimitive attribute.

+7
source

Vladimir’s answer is correct, but the programmer must remember to change the magic number β€œ4” when adding a new member to enum . This definition for turn should be easier to maintain:

 #[derive(Debug, Copy, Clone, FromPrimitive)] enum Direction { NORTH = 0, SOUTH, EAST, WEST, } fn turn(d: Direction) -> Direction { match FromPrimitive::from_u8(d as u8 + 1) { Some(d2) => d2, None => FromPrimitive::from_u8(0).unwrap(), } } 
+5
source

I would prefer to explicitly encode the following direction with the match statement:

 #[derive(Debug)] enum Direction { North, South, East, West, } impl Direction { fn turn(&self) -> Self { use Direction::*; match *self { North => South, South => East, East => West, West => North, } } } fn main() { use Direction::*; for i in &[North, South, East, West] { println!("{:?} -> {:?}", i, i.turn()); } } 
+3
source

Source: https://habr.com/ru/post/1202669/


All Articles