A boolean is a value that can be only one of two things:
true
falseThe boolean type in Zig is:
boolYou use booleans when a program needs to answer a yes-or-no question.
const is_ready: bool = true;
const is_empty: bool = false;A boolean value is usually used with if, while, and other control-flow constructs.
if (is_ready) {
// run this code only when is_ready is true
}Boolean values
The simplest boolean values are written directly:
const a = true;
const b = false;Zig can infer that both values are booleans.
You may also write the type explicitly:
const a: bool = true;
const b: bool = false;A boolean is not an integer. This is important.
In C, numbers can often be used as conditions:
if (1) {
// true in C
}Zig does not allow that style.
This is invalid Zig:
if (1) {
// error
}The condition must be a bool.
Correct Zig code says the condition directly:
const enabled = true;
if (enabled) {
// ok
}This avoids a common class of bugs. Zig does not treat 0 as false or 1 as true.
Comparisons
A comparison asks a question about two values and returns a boolean.
const result = 10 > 5;Here, result is true.
Zig supports the usual comparison operators:
| Operator | Meaning |
|---|---|
== | equal to |
!= | not equal to |
< | less than |
<= | less than or equal to |
> | greater than |
>= | greater than or equal to |
Examples:
const a = 10;
const b = 20;
const x = a == b; // false
const y = a != b; // true
const z = a < b; // trueEach comparison produces a bool.
Using comparisons with if
Comparisons are most often used inside if.
const std = @import("std");
pub fn main() void {
const age = 20;
if (age >= 18) {
std.debug.print("adult\n", .{});
} else {
std.debug.print("minor\n", .{});
}
}Output:
adultThe expression:
age >= 18produces true, so the first branch runs.
Equality and assignment are different
Beginners often confuse these two operators:
=
==Single equals means assignment.
var x = 10;
x = 20;Double equals means comparison.
const same = x == 20;In words:
x = 20 means put 20 into x
x == 20 means ask whether x is equal to 20This distinction is fundamental.
Boolean operators
You can combine booleans with boolean operators.
| Operator | Meaning |
|---|---|
and | both conditions must be true |
or | at least one condition must be true |
! | not |
Example:
const age = 25;
const has_ticket = true;
const can_enter = age >= 18 and has_ticket;can_enter is true only if both conditions are true.
const is_weekend = false;
const is_holiday = true;
const can_sleep_late = is_weekend or is_holiday;can_sleep_late is true if either condition is true.
The ! operator reverses a boolean:
const enabled = false;
const disabled = !enabled; // trueand
The and operator requires both sides to be true.
const a = true;
const b = true;
const c = false;
const x = a and b; // true
const y = a and c; // falseTruth table:
| Left | Right | Result |
|---|---|---|
false | false | false |
false | true | false |
true | false | false |
true | true | true |
Use and when all requirements must be satisfied.
if (username_ok and password_ok) {
// login allowed
}or
The or operator requires at least one side to be true.
const a = true;
const b = false;
const c = false;
const x = a or b; // true
const y = b or c; // falseTruth table:
| Left | Right | Result |
|---|---|---|
false | false | false |
false | true | true |
true | false | true |
true | true | true |
Use or when any one condition is enough.
if (is_admin or is_owner) {
// access allowed
}!
The ! operator means not.
const ready = false;
if (!ready) {
// runs when ready is false
}Read !ready as “not ready.”
Another example:
const file_exists = true;
const missing = !file_exists; // falseShort-circuit behavior
and and or use short-circuit evaluation.
This means Zig may skip the right side if the result is already known.
For and, if the left side is false, the whole expression must be false.
const result = false and expensiveCheck();Here, expensiveCheck() does not need to run.
For or, if the left side is true, the whole expression must be true.
const result = true or expensiveCheck();Again, expensiveCheck() does not need to run.
This is useful when the second condition is safe only after the first condition succeeds.
if (index < items.len and items[index] == 10) {
// safe to access items[index]
}The array access happens only if index < items.len is true.
Comparing integers
Integer comparisons are straightforward:
const a: i32 = -10;
const b: i32 = 5;
const less = a < b; // trueSigned and unsigned integers should be compared carefully. A signed integer can be negative. An unsigned integer cannot.
If two values have different integer types, Zig may require you to convert one explicitly. This keeps the comparison clear.
const a: u32 = 10;
const b: u64 = 20;
const result = @as(u64, a) < b;Here, a is converted to u64 before comparison.
Comparing floats
Floating point comparisons work, but equality is dangerous because floats are approximate.
This is usually fine:
const temperature: f64 = 22.5;
if (temperature > 30.0) {
// hot
}This can be risky:
const x: f64 = 0.1 + 0.2;
if (x == 0.3) {
// may not run
}For floats, prefer comparing with a tolerance when testing equality:
fn nearlyEqual(a: f64, b: f64, tolerance: f64) bool {
return @abs(a - b) < tolerance;
}Then:
if (nearlyEqual(x, 0.3, 0.000001)) {
// close enough
}A complete example
const std = @import("std");
fn canEnter(age: u8, has_ticket: bool, banned: bool) bool {
return age >= 18 and has_ticket and !banned;
}
pub fn main() void {
const age: u8 = 21;
const has_ticket = true;
const banned = false;
if (canEnter(age, has_ticket, banned)) {
std.debug.print("entry allowed\n", .{});
} else {
std.debug.print("entry denied\n", .{});
}
}Output:
entry allowedThe function:
fn canEnter(age: u8, has_ticket: bool, banned: bool) booltakes three inputs and returns a boolean.
The return expression:
age >= 18 and has_ticket and !bannedmeans:
age is at least 18
and the person has a ticket
and the person is not bannedAll three must be true for entry to be allowed.
The main idea
Booleans represent truth values. Comparisons produce booleans. Boolean operators combine booleans.
Zig keeps this strict. Conditions must be real bool values. Integers, pointers, and other values are not automatically treated as true or false.
This makes control flow easier to read and reduces accidental bugs.