for Loop (Array / Slice / Range Iteration)
In Zig, the for statement iterates over arrays, slices, and ranges (integer ranges). The capture syntax |value| extracts each element, and the |value, index| form also retrieves the index at the same time. Multi-iterator parallel traversal over multiple collections is also supported, allowing flexible iteration with a simple syntax.
Syntax
// -----------------------------------------------
// for — iterate over an array or slice
// -----------------------------------------------
for (collection) |value| {
// receives each element as value
}
// -----------------------------------------------
// for — iteration with index
// -----------------------------------------------
for (collection, 0..) |value, i| {
// value : each element
// i : usize index starting from 0
}
// -----------------------------------------------
// for — range (integer range)
// -----------------------------------------------
for (start..end) |i| {
// receives integers from start (inclusive) to end (exclusive) as i
// the end value is not included (half-open interval)
}
// -----------------------------------------------
// for — parallel iteration over multiple collections
// -----------------------------------------------
for (collectionA, collectionB) |a, b| {
// a : each element of collectionA
// b : each element of collectionB (both must have the same length)
}
// -----------------------------------------------
// for as an expression (break with value)
// -----------------------------------------------
const result = for (collection) |value| {
if (condition) break value;
} else defaultValue;
// yields the break value if the condition is met, otherwise the else value
Syntax Reference
| Syntax / Method | Description |
|---|---|
for (arr) |v| { } | Iterates over an array or slice from the beginning. Each element is received as v. |
for (arr, 0..) |v, i| { } | Retrieves both the element and a usize index i (starting from 0) at the same time. |
for (start..end) |i| { } | Iterates over integers from start (inclusive) to end (exclusive) in order (half-open interval). |
for (a, b) |va, vb| { } | Iterates over two collections of the same length in parallel. |
for (arr) |*v| { } | Receives a pointer to each element. You can read and write the value via v.*. |
break | Exits the for loop early. |
continue | Skips the current iteration and advances to the next element. |
break value | Returns a value when for is used as an expression. Used together with an else clause. |
for (...) |v| { } else { } | Executes the else block when the loop completes without hitting a break. |
Sample Code
steinsgate_for_loop.zig
// steinsgate_for_loop.zig — sample code for the for statement
// Uses Steins;Gate characters to demonstrate
// array, slice, range, parallel iteration, and indexed iteration
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
// -----------------------------------------------
// Basic for — iterates over an array in order
// -----------------------------------------------
// Defines lab member names in an array
// [_] lets the compiler infer the number of elements
const members = [_][]const u8{
"Okabe Rintaro",
"Makise Kurisu",
"Shiina Mayuri",
"Hashida Itaru",
"Kiryu Moeka",
};
try stdout.print("=== Future Gadget Lab — Member List ===\n\n", .{});
// Retrieves each element from the array using for
for (members) |name| {
try stdout.print(" Member: {s}\n", .{name});
}
try stdout.print("\n", .{});
// -----------------------------------------------
// Indexed iteration — retrieves the index with 0..
// -----------------------------------------------
// Lab member numbers start from 001 by convention, so we add 1 when printing
try stdout.print("--- Member List with Numbers ---\n", .{});
// i in |name, i| is a usize index (starting from 0)
for (members, 0..) |name, i| {
try stdout.print(" Member{d:0>3}: {s}\n", .{ i + 1, name });
}
try stdout.print("\n", .{});
// -----------------------------------------------
// Range — iterates over an integer range
// -----------------------------------------------
// Prints D-MAIL send counts from 1 to 5
// 0..5 is a half-open interval that generates 0, 1, 2, 3, 4
try stdout.print("--- D-MAIL Send Log (1st to 5th) ---\n", .{});
for (1..6) |count| {
try stdout.print(" Send #{d}: Sent to the past\n", .{count});
}
try stdout.print("\n", .{});
// -----------------------------------------------
// Parallel iteration — iterates over two arrays simultaneously
// -----------------------------------------------
// Defines lab member code names in a separate array
const codenames = [_][]const u8{
"Hououin Kyouma",
"Christina",
"Mayushii",
"Daru",
"Part-time Warrior",
};
// Traverses members and codenames in parallel
// A compile error occurs if the lengths differ
try stdout.print("--- Members and Code Names ---\n", .{});
for (members, codenames) |name, codename| {
try stdout.print(" {s} → {s}\n", .{ name, codename });
}
try stdout.print("\n", .{});
// -----------------------------------------------
// Pointer capture — modifies elements in place
// -----------------------------------------------
// Defines worldline divergence values (percentage) in a var array
// *v receives a pointer to each element; v.* reads or writes the value
var divergences = [_]f32{ 0.571024, 1.048596, 1.130426, 1.382733, 0.000000 };
try stdout.print("--- Worldline Divergence (before) ---\n", .{});
for (divergences) |d| {
try stdout.print(" {d:.6}\n", .{d});
}
// Adds 0.1 to every divergence value
for (&divergences) |*d| {
d.* += 0.1;
}
try stdout.print("--- Worldline Divergence (after +0.1) ---\n", .{});
for (divergences) |d| {
try stdout.print(" {d:.6}\n", .{d});
}
try stdout.print("\n", .{});
// -----------------------------------------------
// for as an expression — returns a value with break
// -----------------------------------------------
// Searches for the index of "Makise Kurisu"
// break returns the value; if not found, else returns null
const target = "Makise Kurisu";
const found_index: ?usize = for (members, 0..) |name, i| {
if (std.mem.eql(u8, name, target)) break i;
} else null;
if (found_index) |idx| {
try stdout.print("{s} — Member Number: {d:0>3}\n", .{ target, idx + 1 });
} else {
try stdout.print("{s} was not found\n", .{target});
}
}
zig run steinsgate_for_loop.zig === Future Gadget Lab — Member List === Member: Okabe Rintaro Member: Makise Kurisu Member: Shiina Mayuri Member: Hashida Itaru Member: Kiryu Moeka --- Member List with Numbers --- Member001: Okabe Rintaro Member002: Makise Kurisu Member003: Shiina Mayuri Member004: Hashida Itaru Member005: Kiryu Moeka --- D-MAIL Send Log (1st to 5th) --- Send #1: Sent to the past Send #2: Sent to the past Send #3: Sent to the past Send #4: Sent to the past Send #5: Sent to the past --- Members and Code Names --- Okabe Rintaro → Hououin Kyouma Makise Kurisu → Christina Shiina Mayuri → Mayushii Hashida Itaru → Daru Kiryu Moeka → Part-time Warrior --- Worldline Divergence (before) --- 0.571024 1.048596 1.130426 1.382733 0.000000 --- Worldline Divergence (after +0.1) --- 0.671024 1.148596 1.230426 1.482733 0.100000 Makise Kurisu — Member Number: 002
Overview
The for statement in Zig is the syntax for iterating over arrays, slices, and integer ranges. The capture syntax |value| receives each element, and the |value, index| form also retrieves the index at the same time. The index is always of type usize, and the starting value is specified as 0... Integer ranges are written as a half-open interval start..end (end is not included), so for (1..6) |i| passes 1, 2, 3, 4, 5 in sequence.
To traverse two collections in parallel, use the form for (a, b) |va, vb| { }. If the two collections have different lengths, a compile error occurs. To modify element values in place, use the pointer capture |*v| and read or write via v.*. Additionally, for can be used as an expression that returns a value — combining break value with an else clause makes it easy to write logic such as "return the first element that satisfies a condition." For related topics, see Array Basics and Slices.
If you find any errors or copyright issues, please contact us.