Enums
Enums define types with a fixed set of variants, optionally carrying data.
Basic Enums
Definition
enum Color {
Red,
Green,
Blue,
}Creating Enum Values
Use :: syntax to create enum variants:
let c: Color = Color::Red
let g: Color = Color::GreenPattern Matching
Use match to handle enum variants:
fn to_rgb(c: Color) -> (i32, i32, i32) {
var r: i32 = 0
var g: i32 = 0
var b: i32 = 0
match c {
Color.Red => { r = 255 }
Color.Green => { g = 255 }
Color.Blue => { b = 255 }
}
return (r, g, b)
}Note: Match patterns use . (not ::) for variants.
Enums with Payloads
Variants can carry data:
enum Message {
Text(string),
Number(i32),
Position(i32, i32),
Empty,
}Creating Payload Variants
let m1: Message = Message::Text("hello")
let m2: Message = Message::Number(42)
let m3: Message = Message::Position(10, 20)
let m4: Message = Message::EmptyExtracting Payloads
Use pattern matching to extract data:
fn process(msg: Message) -> void {
match msg {
Message.Text(s) => {
println("Text: {s}")
}
Message.Number(n) => {
println("Number: {n}")
}
Message.Position(x, y) => {
println("Position: ({x}, {y})")
}
Message.Empty => {
println("Empty message")
}
}
}Generic Enums
Enums can have type parameters:
enum MyOption#[T] {
MySome(T),
MyNone,
}Creating Generic Enum Values
Specify the type parameter with the enum name:
let some_int: MyOption#[i32] = MyOption#[i32]::MySome(42)
let none_int: MyOption#[i32] = MyOption#[i32]::MyNonePattern Matching Generic Enums
fn unwrap_or#[T](opt: MyOption#[T], default: T) -> T {
var result: T
match opt {
MyOption.MySome(value) => { result = value }
MyOption.MyNone => { result = default }
}
return result
}Built-in Enums
Option#[T] (written as ?T)
The optional type for values that may or may not exist:
let some_value: ?i32 = Some(42)
let no_value: ?i32 = NoneSee Optional for details.
Result#[T, E]
The result type for operations that may fail:
let success: Result#[i32, string] = Ok(42)
let failure: Result#[i32, string] = Err("something went wrong")See Result for details.
Implementing Methods on Enums
Use impl blocks to add methods:
enum Direction {
North,
South,
East,
West,
}
impl Direction {
fn opposite(self: Direction) -> Direction {
var result: Direction
match self {
Direction.North => { result = Direction::South }
Direction.South => { result = Direction::North }
Direction.East => { result = Direction::West }
Direction.West => { result = Direction::East }
}
return result
}
}Implementing Traits on Enums
trait Describable {
fn describe(self: Self) -> string
}
impl Color: Describable {
fn describe(self: Color) -> string {
var desc: string
match self {
Color.Red => { desc = "The color red" }
Color.Green => { desc = "The color green" }
Color.Blue => { desc = "The color blue" }
}
return desc
}
}Example: Expression Tree
enum Expr {
Number(i32),
Add(Rc#[Expr], Rc#[Expr]),
Multiply(Rc#[Expr], Rc#[Expr]),
}
fn eval(e: Expr) -> i32 {
var result: i32
match e {
Expr.Number(n) => {
result = n
}
Expr.Add(left, right) => {
result = eval(left.get()) + eval(right.get())
}
Expr.Multiply(left, right) => {
result = eval(left.get()) * eval(right.get())
}
}
return result
}Example: State Machine
enum ConnectionState {
Disconnected,
Connecting(string), // server address
Connected(i32), // connection id
Error(string), // error message
}
fn describe_state(state: ConnectionState) -> string {
var desc: string
match state {
ConnectionState.Disconnected => {
desc = "Not connected"
}
ConnectionState.Connecting(addr) => {
desc = "Connecting to {addr}..."
}
ConnectionState.Connected(id) => {
desc = "Connected (id: {id})"
}
ConnectionState.Error(msg) => {
desc = "Error: {msg}"
}
}
return desc
}Next Steps
- Traits - Implementing traits on enums
- Generics - Generic enums
- Error Handling - Using Result and Option