带有Rust中构造的枚举

问题描述 投票:2回答:3

我有Java的现有实现,必须将其重写为Rust。

Java代码

enum Direction {
    EAST(0), WEST(180), NORTH(90), SOUTH(270);

    private Direction(final int angle) {
        this.angle = angle;
    }

    private int angle;

    public int getAngle() {
        return angle;
    }
}

Java代码用法示例

Direction d1 = Direction.EAST;
Direction d2 = Direction.SOUTH;

锈码

所以这是我尝试过的:

enum Direction {
    East(u32), 
    West(u32), 
    North(u32), 
    South(u32);
}

impl Direction {
    // ???
    fn new() -> Direction // incorrect
}

然后我被困住了。接下来我该怎么办?

enums rust
3个回答
11
投票

这是您的Java枚举的样子:

+-----+-----+
| tid |   0 |
+-----+-----+
+-----+-----+
| tid |  90 |
+-----+-----+
+-----+-----+
| tid | 180 |
+-----+-----+
+-----+-----+
| tid | 270 |
+-----+-----+

tid在所有四个方向上都是相同的,并标识类型Direction及其方法。使用您的Rust代码的East(0)Noth(90)West(180)South(270)如下所示:

+-------+-----+-----+-----+-----+
| East  |   0 |     |     |     |
+-------+-----+-----+-----+-----+
+-------+-----+-----+-----+-----+
| North |     |  90 |     |     |
+-------+-----+-----+-----+-----+
+-------+-----+-----+-----+-----+
| West  |     |     | 180 |     |
+-------+-----+-----+-----+-----+
+-------+-----+-----+-----+-----+
| South |     |     |     | 270 |
+-------+-----+-----+-----+-----+

每个构造函数都有一组不同的字段(在这种情况下,每个字段int)。实际上,由于任何给定的Direction最多是East/North/East/West之一,因此在任何时间点仅使用一组字段,并且它们使用相同的内存(因此Direction实际上仅占用两个单词)。

但是从概念上讲,以上是正确的,并说明了Rust版本的两个问题。首先,存在重复:构造函数标记(N / E / S / W)对于所有四个都已经不同,因此int字段是多余的。其次,从概念上讲,int中的Northint中的South完全不同,尽管它们的含义完全相同。此外,没有什么可以阻止创建North(214)East(180)

最直接的翻译是这样:

enum Direction { North, East, South, West }

impl Direction {
  fn get_angle(self) -> int {
    match self {
      East => 0,
      West => 180,
      North => 90,
      South => 270,
    }
  }
}

方向在枚举标记中隐含,并用get_angle提取。


10
投票

delnan的答案是绝对正确的,您可能应该这样做,但是还有另一种方法。 Rust枚举也可以类似于C枚举,C枚举常量本质上是数字常量。 Rust允许您编写如下内容:

enum Direction {
    East = 0,
    North = 90,
    West = 180,
    South = 270
}

然后您可以将枚举值用作带有显式强制转换的数字:

let value = South as uint;
println!("{}", value);  // prints 270

这是有效的,因为枚举本质上是带有隐藏鉴别符字段(即数字)的结构。因此,没有变量变体的枚举的值仅包含此歧视字段。可以通过数字强制转换来访问其值,并且可以在枚举定义中为不同的枚举变量设置具体的值。

我的意思是,这仅在需要整数时才有效。您不能像在Java中那样获得字符串或浮点数,就像在Java中那样(枚举变量只是具有任意字段的常规对象)。如果需要,则必须使用单独的getter方法,就像在delnan的答案中一样。


0
投票

Edit:我不知道Java枚举已关闭。因此,您可能应该使用delnan的答案。

我认为您想要这样的东西:

pub struct Direction {
    angle: int,
}

impl Direction {
    pub fn new(angle: int) -> Direction {
        Direction {
            angle: angle,
        }
    }

    pub fn get_angle(&self) -> int {
        self.angle
    }
}

pub const EAST: Direction = Direction { angle: 0 };
pub const WEST: Direction = Direction { angle: 180 };
pub const NORTH: Direction = Direction { angle: 90 };
pub const SOUTH: Direction = Direction { angle: 270 };

说明:Rust中的enum用于列出有限的不相交变体集。换句话说,如果enum可以onlyDirectionEastWestNorth而不是其他任何内容,则South将是合适的。

© www.soinside.com 2019 - 2024. All rights reserved.