if
if.zig
// If expressions have three uses, corresponding to the three types:
// * bool
// * ?T
// * anyerror!T
const expect = @import("std").testing.expect;
test "if expression" {
// If expressions are used instead of a ternary expression.
const a: u32 = 5;
const b: u32 = 4;
const result = if (a != b) 47 else 3089;
expect(result == 47);
}
test "if boolean" {
// If expressions test boolean conditions.
const a: u32 = 5;
const b: u32 = 4;
if (a != b) {
expect(true);
} else if (a == 9) {
unreachable;
} else {
unreachable;
}
}
test "if optional" {
// If expressions test for null.
const a: ?u32 = 0;
if (a) |value| {
expect(value == 0);
} else {
unreachable;
}
const b: ?u32 = null;
if (b) |value| {
unreachable;
} else {
expect(true);
}
// The else is not required.
if (a) |value| {
expect(value == 0);
}
// To test against null only, use the binary equality operator.
if (b == null) {
expect(true);
}
// Access the value by reference using a pointer capture.
var c: ?u32 = 3;
if (c) |*value| {
value.* = 2;
}
if (c) |value| {
expect(value == 2);
} else {
unreachable;
}
}
test "if error union" {
// If expressions test for errors.
// Note the |err| capture on the else.
const a: anyerror!u32 = 0;
if (a) |value| {
expect(value == 0);
} else |err| {
unreachable;
}
const b: anyerror!u32 = error.BadValue;
if (b) |value| {
unreachable;
} else |err| {
expect(err == error.BadValue);
}
// The else and |err| capture is strictly required.
if (a) |value| {
expect(value == 0);
} else |_| {}
// To check only the error value, use an empty block expression.
if (b) |_| {} else |err| {
expect(err == error.BadValue);
}
// Access the value by reference using a pointer capture.
var c: anyerror!u32 = 3;
if (c) |*value| {
value.* = 9;
} else |err| {
unreachable;
}
if (c) |value| {
expect(value == 9);
} else |err| {
unreachable;
}
}
test "if error union with optional" {
// If expressions test for errors before unwrapping optionals.
// The |optional_value| capture's type is ?u32.
const a: anyerror!?u32 = 0;
if (a) |optional_value| {
expect(optional_value.? == 0);
} else |err| {
unreachable;
}
const b: anyerror!?u32 = null;
if (b) |optional_value| {
expect(optional_value == null);
} else |err| {
unreachable;
}
const c: anyerror!?u32 = error.BadValue;
if (c) |optional_value| {
unreachable;
} else |err| {
expect(err == error.BadValue);
}
// Access the value by reference by using a pointer capture each time.
var d: anyerror!?u32 = 3;
if (d) |*optional_value| {
if (optional_value.*) |*value| {
value.* = 9;
}
} else |err| {
unreachable;
}
if (d) |optional_value| {
expect(optional_value.? == 9);
} else |err| {
unreachable;
}
}
$ zig test if.zig
1/5 test "if expression"... OK
2/5 test "if boolean"... OK
3/5 test "if optional"... OK
4/5 test "if error union"... OK
5/5 test "if error union with optional"... OK
All 5 tests passed.
See also: