Enumerated types (enum
)
In Java, an enum
is a specialized type of class that has limited functionality. An enum holds a small number of possible permissible values of a type.
Here's an example of an enum in Java:
enum PrimaryColor {
RED,
GREEN,
BLUE
}
Rust has an identical syntax for declaring the same enum:
enum PrimaryColor {
Red,
Green,
Blue
}
Being specialized classes in Java, enums can have member fields and methods. Here's an example for illustration purposes:
enum RainbowColor {
RED(1),
ORANGE(2),
YELLOW(3),
GREEN(4),
BLUE(5),
INDIGO(6),
VIOLET(7); // the semi colon at the end of list required for enums with parameters
private final int number;
private final String name;
public int getNumber() {
return number;
}
public String getName() {
return name;
}
RainbowColor(int number) {
this.number = number;
this.name = switch (number) {
case 1 -> "RED";
case 2 -> "ORANGE";
case 3 -> "YELLOW";
case 4 -> "GREEN";
case 5 -> "BLUE";
case 6 -> "INDIGO";
case 7 -> "VIOLET";
default -> throw new RuntimeException("Illegal: " + number);
};
}
}
Here's how we could exercise the RainbowColor
enum:
public class RainbowColorTest {
public static void main(String[] args) {
RainbowColor color = RainbowColor.BLUE;
String name = color.getName();
System.out.println(name); // prints: BLUE
}
}
A slightly similar (not a 1:1 mapping) version of the RainbowColor
enum in Rust is shown below:
#[derive(Debug)] // enables formatting in "{:?}"
enum RainbowColor {
Red = 1,
Orange = 2,
Yellow = 3,
Green = 4,
Blue = 5,
Indigo = 6,
Violet = 7,
}
impl RainbowColor {
fn new(number: i32) -> Result<RainbowColor, Box<dyn std::error::Error>> {
use RainbowColor::*;
match number {
1 => Ok(Red),
2 => Ok(Orange),
3 => Ok(Yellow),
4 => Ok(Green),
5 => Ok(Blue),
6 => Ok(Indigo),
7 => Ok(Violet),
_ => return Err(format!("Illegal: {}", number).into())
}
}
}
The new()
function returns a RainbowColor
in a Result
indicating success
(Ok
) if number
is valid. Otherwise it panics:
let color = RainbowColor::new(5);
println!("{color:?}"); // prints: Ok(Blue)
let color = RainbowColor::new(10);
println!("{color:?}"); // prints: Err("Illegal: 10")
An enum
type in Rust can also serve as a way to design (discriminated) union
types, which allow different variants to hold data specific to each variant.
For example:
enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));
Enums in Rust are most similar to algebraic data types in functional languages, such as OCaml and Haskell.