Enums
Basic enums
enum Direction : u8 {
North; // 0
East; // 1
South; // 2
West; // 3
}
let facing: Direction = Direction.North;A variant without a value is the previous one plus 1, and the first is 0. A value can be given anywhere and the count goes on from it:
enum Status : i16 {
Ok; // 0
Retry = 10;
Busy; // 11
}When an enum is shared with C, written to a file or sent over the network, write every value, so that adding or reordering a variant can’t change the numbers the other side relies on.
Every enum is its own type
An enum value goes only where its own enum is declared. Its integer is how it
is stored, not its type, so converting to or from an integer is written as:
enum Color : u8 { Red = 0; Green = 1; }
let d: Direction = Direction.East;
let n: u8 = d as u8; // 1
let back: Direction = n as Direction; // Direction.East
let next: Direction = ((d as i64 + 1) % 4) as Direction;
let bad1: Direction = Color.Green; // error: 'bad1' is Direction, given Color
let bad2: Direction = 1; // error: an integer becomes an enum only with 'as'
let bad3: i64 = d; // error: an enum becomes an integer only with 'as'
if (d == Color.Green) { } // error: cannot compare 'Direction' with 'Color'
let bad4 = d + 1; // error: arithmetic on enum 'Direction'- Values of one enum compare with
==,!=and, by their values,<,<=,>,>=. An enum never compares with an integer or with another enum. asconverts an enum to any integer type and an integer to an enum. One enum to another goes through an integer:(c as i64) as Direction.askeeps a value no variant has. For an integer read from a file, a protocol or the runtime, useE.from_value(n)instead (below).- The same holds for enum fields, parameters, returns, consts,
?Eand the error ofT or E. Two enums with the same name in different modules are different types; one enum reached through two imports is one type.
Enums with descriptions
enum HttpStatus : u16 {
Ok = 200: "success";
NotFound = 404: "not found";
ServerError = 500: "internal server error";
}The description string is accessible at runtime:
let msg: []const u8 = HttpStatus.desc(HttpStatus.NotFound);
// "not found"Checked conversion: from_value
E.from_value(n) gives the variant whose value is n, or null when there is
none. It takes any integer type and compares by value, so a number outside
the backing type’s range is null rather than wrapped:
fn parse_dir(raw: u8) -> Direction or ParseErr {
let d = Direction.from_value(raw); // ?Direction
if (d == null) { return ParseErr.BadInput; }
return d!;
}
Direction.from_value(2) // Direction.South
Direction.from_value(9) // nullIt works on an imported enum too: geo.Direction.from_value(n).
Backing type
The : u8 suffix specifies the underlying integer type. Any integer type works:
enum BigEnum : u32 {
First = 0;
Last = 0xFFFFFFFF;
}
enum Sign : i8 { Minus = -1; Zero = 0; Plus = 1; }Matching on enums
Use match to branch on enum values:
match (facing) {
Direction.North => { move(0, -1); }
Direction.East => { move(1, 0); }
Direction.South => { move(0, 1); }
Direction.West => { move(-1, 0); }
}Use _ as a wildcard catch-all:
match (facing) {
Direction.North => { move(0, -1); }
_ => { io.println("not north"); }
}Match must be exhaustive — all variants must be covered, or _ must be present.
An arm can list several variants: Direction.East, Direction.West => { ... }
(see Control flow).
As error types
Enums are commonly used as error types with T or E:
enum ParseErr : u8 {
BadInput = 1: "invalid input";
Overflow = 2: "value too large";
}
fn parse(s: string) -> i64 or ParseErr {
// ...
}Last modified: