# Switch

> Exhaustive by construction.

```zig
const std = @import("std");
const expect = std.testing.expect;

test "switch as a statement" {
    var x: i8 = 10;
    switch (x) {
        -1...1 => x = -x, // inclusive ranges
        10, 100 => x = @divExact(x, 10), // multiple values
        else => {},
    }
    try expect(x == 1);
}

test "switch as an expression" {
    const x: i8 = 10;
    const y: i8 = switch (x) {
        -1...1 => -x,
        10, 100 => @divExact(x, 10),
        else => 0,
    };
    try expect(y == 1);
}

const Direction = enum { north, south, east, west };

fn isVertical(d: Direction) bool {
    // No `else` branch: the compiler proves every case is handled, so adding
    // a new enum tag later turns this into a compile error rather than a bug.
    return switch (d) {
        .north, .south => true,
        .east, .west => false,
    };
}

test "exhaustive switch over an enum" {
    try expect(isVertical(.north));
    try expect(!isVertical(.east));
}
```

*Runnable: compiled to WebAssembly and executed by CI against Zig master. (`02-language.switch`)*

Zig's `switch` has no fallthrough, and it must be **exhaustive**: every possible
value needs a branch, or the program does not compile.

## Ranges and multiple values

```zig
switch (x) {
    -1...1 => ...,      // inclusive range
    10, 100 => ...,     // several values, one branch
    else => ...,
}
```

Note `...` for ranges is inclusive on both ends, unlike the `..` used in `for`
ranges, which excludes the upper bound.

## The exhaustiveness payoff

When switching over an enum and covering every tag, **leave out `else`**:

```zig
return switch (direction) {
    .north, .south => true,
    .east, .west => false,
};
```

Now adding a `.up` variant later turns this into a compile error pointing
straight at the code that needs updating. Adding `else => false` would instead
silently classify the new direction as horizontal. The `else` branch is a
convenience that costs you the compiler's help. Spend it deliberately.
