On this page
article
Chapter 7: Enums and Unions
Enums — Fieldless Variants
type Direction = enum {
North,
South,
East,
West,
};
var d = Direction.North;
-- enums are always Copy
case d {
.North => debug.print("going north\n"),
.South => debug.print("going south\n"),
.East => debug.print("going east\n"),
.West => debug.print("going west\n"),
}
Unions — Tagged Variants With Data
type Shape = union {
Circle { radius: f32 },
Rectangle { width: f32, height: f32 },
Triangle { base: f32, height: f32 },
Point, -- unit variant, no data
};
fn area(shape: Shape): f32 {
return case shape {
.Circle { radius } => 3.14159 * radius * radius,
.Rectangle { width, height } => width * height,
.Triangle { base, height } => 0.5 * base * height,
.Point => 0.0,
};
}
var s = Shape.Circle { .radius = 5.0 };
debug.print("area: {}\n", .{area(s)});
Optionals — ?T
An optional is either a value or nothing:
var x: ?i32 = 5;
var y: ?i32 = .None;
-- four ways to handle optionals:
-- orelse: provide a default
var n = x orelse 0;
var n = x orelse return error.Missing;
-- ? operator: propagate None upward
var n = x?;
-- if unwrap
if x |val| {
debug.print("got {}\n", .{val});
}
-- case
case x {
.Some { value } => debug.print("got {}\n", .{value}),
.None => debug.print("nothing\n"),
}
Finding something in a list:
fn findFirst(items: []const i32, target: i32): ?usize {
for item, i in items {
if item.* = target { return i; }
}
return .None;
}
if findFirst(&.{1, 2, 3, 4, 5}, 3) |idx| {
debug.print("found at index {}\n", .{idx});
}
Pattern Guards
case shape {
.Circle { radius } if radius > 10.0 => debug.print("large circle\n"),
.Circle { radius } => debug.print("small circle\n"),
_ => debug.print("other shape\n"),
}