switch
switch.zig
const assert = @import("std").debug.assert;
const builtin = @import("builtin");
test "switch simple" {
const a: u64 = 10;
const zz: u64 = 103;
// All branches of a switch expression must be able to be coerced to a
// common type.
//
// Branches cannot fallthrough. If fallthrough behavior is desired, combine
// the cases and use an if.
const b = switch (a) {
// Multiple cases can be combined via a ','
1, 2, 3 => 0,
// Ranges can be specified using the ... syntax. These are inclusive
// both ends.
5...100 => 1,
// Branches can be arbitrarily complex.
101 => blk: {
const c: u64 = 5;
break :blk c * 2 + 1;
},
// Switching on arbitrary expressions is allowed as long as the
// expression is known at compile-time.
zz => zz,
comptime blk: {
const d: u32 = 5;
const e: u32 = 100;
break :blk d + e;
} => 107,
// The else branch catches everything not already captured.
// Else branches are mandatory unless the entire range of values
// is handled.
else => 9,
};
assert(b == 1);
}
// Switch expressions can be used outside a function:
const os_msg = switch (builtin.os) {
builtin.Os.linux => "we found a linux user",
else => "not a linux user",
};
// Inside a function, switch statements implicitly are compile-time
// evaluated if the target expression is compile-time known.
test "switch inside function" {
switch (builtin.os) {
builtin.Os.fuchsia => {
// On an OS other than fuchsia, block is not even analyzed,
// so this compile error is not triggered.
// On fuchsia this compile error would be triggered.
@compileError("fuchsia not supported");
},
else => {},
}
}
$ zig test switch.zig
Test 1/2 switch simple...OK
Test 2/2 switch inside function...OK
All tests passed.
switch
can be used to capture the field values of a Tagged union. Modifications to the field values can be done by placing a *
before the capture variable name, turning it into a pointer.
test.zig
const assert = @import("std").debug.assert;
test "switch on tagged union" {
const Point = struct {
x: u8,
y: u8,
};
const Item = union(enum) {
A: u32,
C: Point,
D,
};
var a = Item{ .C = Point{ .x = 1, .y = 2 } };
// Switching on more complex enums is allowed.
const b = switch (a) {
// A capture group is allowed on a match, and will return the enum
// value matched.
Item.A => |item| item,
// A reference to the matched value can be obtained using `*` syntax.
Item.C => |*item| blk: {
item.*.x += 1;
break :blk 6;
},
// No else is required if the types cases was exhaustively handled
Item.D => 8,
};
assert(b == 6);
assert(a.C.x == 2);
}
$ zig test test.zig
Test 1/1 switch on tagged union...OK
All tests passed.
See also: