If Expressions
const std = @import("std");
const expect = std.testing.expect;
test "if as a statement" {
const a = true;
var x: u16 = 0;
if (a) {
x += 1;
} else {
x += 2;
}
try expect(x == 1);
}
test "if as an expression" {
const a = true;
// The ternary equivalent; both branches must yield the same type.
const x: u16 = if (a) 1 else 2;
try expect(x == 1);
}
test "if unwraps an optional" {
const maybe: ?u8 = 42;
const doubled: u16 = if (maybe) |value| value * 2 else 0;
try expect(doubled == 84);
}There is no truthiness in Zig. if (1) does not compile; neither does
if (pointer). The condition must be a bool, which removes an entire family
of bugs where a value is accidentally treated as a flag.
if produces a value
Zig has no ternary operator because it does not need one:
const x: u16 = if (a) 1 else 2;
Both branches must agree on a type. Used as an expression, the else is
mandatory: there would otherwise be no value when the condition is false.
Unwrapping
if is also how you get inside an optional, using payload capture:
if (maybe) |value| { ... } else { ... }
The same shape works for error unions with else |err|. This is a recurring
theme: the check and the unwrap are one construct, so they cannot fall out of
sync.