Zig by Example: Switch

Switch works as both a statement and an expression.

const std = @import("std");
const print = std.debug.print;
pub fn main() !void {
    var x: i8 = 10;

An example of a switch statement. The else is required to satisfy the exhaustiveness of this switch. All possible values must have an associated branch, values cannot be left out. Cases cannot fall through to other branches.

    switch (x) {
        -1...1 => {
            x = -x;
        },
        10, 100 => print("x: {d}\n", .{x}),
        else => {},
    }

Here the classic FizzBuzz exercise using a switch statement.

    var count: u8 = 1;
    while (count <= 15) : (count += 1) {

After define while to count until 15 we use @intFromBool which converts true to 1 and false to 0 resulting into a u1 value (i.e. a 1 bit unsigned integer).

        const div3: u2 = @intFromBool(count % 3 == 0);

You may notice that we haven’t given div5 an explicit type, this is because it is inferred from the value that is assigned to it.

        const div5 = @intFromBool(count % 5 == 0);

We need u2 to fit two booleans and perform this multiplication of div3, you can see the binary notation in action as result to satisfy the expression evaluated. We can rewrite the switch value to use bitwise operations: switch (div3 << 1 | div5).

        switch (div3 * 2 + div5) {
            0b10 => print("Fizz\n", .{}),
            0b01 => print("Buzz\n", .{}),
            0b11 => {
                print("Fizz", .{});
                print("Buzz\n", .{});
            },
            else => print("{d}\n", .{count}),
        }
    }

switch can also be used as expression.

    x = switch (x) {
        -1...1 => -x,
        10, 100 => @divExact(x, 10),
        else => x,
    };
    print("x: {d}\n", .{x});
}
$ zig run switch.zig
x: 10
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
x: 1