Switch Statements
A switch lets us distinguish different values of a basic type. It has a branch for each possible value:
const std = @import("std");
const print = std.debug.print;
fn printNumber(n: u2) void {
// switch statement
switch (n) {
0 => print("zero\n", .{}),
1 => print("one\n", .{}),
2 => print("two\n", .{}),
3 => print("three\n", .{}),
}
}
fn abs(n: i2) u2 {
// switch expression
return switch (n) {
-2 => 2,
-1 => 1,
0 => 0,
1 => 1,
};
}
pub fn main() void {
printNumber(3);
print("abs({d}) = {d}\n", .{ -1, abs(-1) });
}$ zig run switch-1.zig
three
abs(-1) = 1
There are ways to use a branch for multiple values:
const std = @import("std");
const print = std.debug.print;
fn characterType(c: u64) []const u8 {
return switch (c) {
' ' => "space",
'_' => "underscore",
// Use '...' for a range of values.
'0'...'9' => "digit",
'a'...'z' => "lower-case letter",
'A'...'Z' => "upper-case letter",
// Combine multiple cases with commas.
'ä', 'ö', 'ü' => "lower-case umlaut",
'Ä', 'Ö', 'Ü' => "upper-case umlaut",
// An 'else' matches all remaining cases.
else => "unknown character",
};
}
pub fn main() void {
print("ä: {s}\n", .{characterType('ä')});
}$ zig run switch-2.zig
ä: lower-case umlaut
A branch can be a block instead of a single expression:
const std = @import("std");
const print = std.debug.print;
fn inc(n: u2) u2 {
switch (n) {
0 => return 1,
1 => return 2,
2 => return 3,
3 => {
print("value out of range!\n", .{});
return 3;
},
}
}
pub fn main() void {
print("inc(3) = {}\n", .{inc(3)});
}$ zig run switch-3.zig
value out of range!
inc(3) = 3
For switch expressions, we need a labeled block:
const std = @import("std");
const print = std.debug.print;
fn dec(n: u2) u2 {
return switch (n) {
0 => blk: {
print("value out of range!\n", .{});
break :blk 0;
},
1 => 0,
2 => 1,
3 => 2,
};
}
pub fn main() void {
print("dec(0) = {}\n", .{dec(0)});
}$ zig run switch-4.zig
value out of range!
dec(0) = 0
Next example: While Loops.