如何通过枚举变体"切换"?

Jac*_*ang 7 rust

我想写一个函数,它将提供的值切换/切换到枚举中的下一个并在结尾处回绕:

enum Direction { NORTH, SOUTH, EAST, WEST }
Run Code Online (Sandbox Code Playgroud)

例如,NORTH=> SOUTH,SOUTH=> EAST,EAST=> WEST,WEST=> NORTH.

有没有比In Rust中描述的手动创建静态数组更简单的方法,有没有办法迭代枚举的值?

use Direction::*;
static DIRECTIONS: [Direction; 4] = [NORTH, SOUTH, EAST, WEST];
Run Code Online (Sandbox Code Playgroud)

是不是枚举假设是"枚举"?我依稀记得在Rust之前看过一个例子,但我似乎无法找到它.由于Rust枚举更像是工会/变体,我想这会让事情复杂化.

gfo*_*our 10

弗拉基米尔的答案是正确的,但程序员必须记住在添加新成员时更改幻数"4" enum.这个定义turn应该更容易维护:

#[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(),
    }
}
Run Code Online (Sandbox Code Playgroud)


Vla*_*eev 7

我猜这样的事情会起到作用:

#[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));
    }
}
Run Code Online (Sandbox Code Playgroud)

这不需要,unsafe因为它使用自动派生的FromPrimitive特征.


She*_*ter 7

我希望通过一条match语句来明确编码下一个方向:

#[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());
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这里“use”的用法很好。谢谢。 (2认同)