After getting comfortable with Variables, types and functions in the first exercises, I moved into control flow. This section covered if, while, for and eventually switch statements -which started out confusing.
If Statements
Straight forward but strict
if (x > 10) {
std.debug.print("Big Number!\n", .{};
} else {
std.debug.print("Small Number.\n", .{};
}
Zig- No implicit truthiness like in JavaScript – conditions must be bool
- Keeps things clear: no guessing what evaluates to true or false.
While Loops
Zig’s while felt rigid at first, but I see why: it avoids surprises.
var i: i32 = 0;
while (i < 3) : (i += 1) {
std.debug.print("{}\n", .{i});
}
Zig- Loop condition is explicit
: (i += 1)
is a continue expression, which runs after each iteration.- Forces me to think about exactly how my loop runs.
For Loops
Similar to other languages, but with Zig’s style of clarity.
const arr = [_]i32{1, 2, 3};
for (arr) |value| {
std.debug.print("{}\n", .{value});
}
Zig- iterates directly over arrays and slices
- The
|value|
syntax binds the current element. - Simple, clean, no hidden rules.
Switch Statements
This was a big challenge to wrap my head around.
const day = 3;
switch (day) {
1 => std.debug.print("Monday\n", .{}),
2 => std.debug.print("Tuesday\n", .{}),
3 => std.debug.print("Wednesday\n", .{}),
else => std.debug.print("Another Day\n", .{}),
}
Zig- Exhaustive: You must handle all cases, or use else.
- Works with enums, ranges, and more – not just integers.
Reflection
This section really showed me Zig’s philosophy: clarity over magic.
- Ifs and loops are predictable – no hidden type coercion.
- Switch statements are powerful but force you to think carefully.
The surprise here is that so far this is not as hard as i made it to be in my head.
Looking Ahead
Next up, Ziglings moves into error handling and optionals. I’ve heard that Zig handles errors in a very unique way, so I’m curious to see how it compares to other languages.