Enums
An enum is a custom type with a fixed list of pre-defined values (called fields or tags):
const std = @import("std");
const print = std.debug.print;
const Color = enum {
red,
green,
blue,
fn isRed(self: Color) bool {
return self == .red;
}
};
pub fn main() void {
// Two ways to initialize an enum:
const a = Color.green;
const b: Color = .green;
// Print with {}, or {t} to get just the tag.
print("a is {}\n", .{a});
print("b is {t}\n", .{b});
print("a is red? {}\n", .{a.isRed()});
if (a == .green)
print("a is green\n", .{});
const color_code: u24 = switch (a) {
.red => 0xcc0000,
.green => 0x66cc00,
.blue => 0x0000ff,
};
print("color code: {X:06}\n", .{color_code});
}$ zig run enums.zig
a is .green
b is green
a is red? false
a is green
color code: 66CC00
Ordinal values
Each tag of an enum is assigned a small integer value. By default, they’re numbered starting from 0:
const std = @import("std");
const print = std.debug.print;
const Color = enum { red, green, blue };
pub fn main() void {
print("tag type: {}\n", .{
@TypeOf(@intFromEnum(Color.red)),
});
print("ordinal values: {} {} {}\n", .{
@intFromEnum(Color.red),
@intFromEnum(Color.green),
@intFromEnum(Color.blue),
});
const c: Color = @enumFromInt(2);
print("color 2 is {t}\n", .{c});
}$ zig run enums-2.zig
tag type: u2
ordinal values: 0 1 2
color 2 is blue
We can override the ordinal type and values:
const std = @import("std");
const print = std.debug.print;
const Color = enum(u24) {
red = 0xcc0000,
green = 0x66cc00,
blue = 0x0000ff,
};
pub fn main() void {
print("ordinal type: {}\n", .{
@TypeOf(@intFromEnum(Color.red)),
});
print("ordinal values: {X:06} {X:06} {X:06}\n", .{
@intFromEnum(Color.red),
@intFromEnum(Color.green),
@intFromEnum(Color.blue),
});
}$ zig run enums-3.zig
ordinal type: u24
ordinal values: CC0000 66CC00 0000FF
Adding a _ tag makes an enum a non-exhaustive
enum, which means it can have any ordinal value:
const std = @import("std");
const print = std.debug.print;
const Color = enum(u24) {
red = 0xcc0000,
green = 0x66cc00,
blue = 0x0000ff,
_,
fn frenchName(self: Color) []const u8 {
return switch (self) {
.red => "rouge",
.green => "vert",
.blue => "bleu",
_ => "couleur mystérieuse",
};
}
};
pub fn main() void {
const a: Color = .green;
const b: Color = @enumFromInt(0xffffff);
print("{}: {s}\n", .{ a, a.frenchName() });
print("{}: {s}\n", .{ b, b.frenchName() });
}$ zig run non-exhaustive.zig
.green: vert
@enumFromInt(16777215): couleur mystérieuse
Next example: Unions.