master
 1const expect = @import("std").testing.expect;
 2
 3test "for basics" {
 4    const items = [_]i32{ 4, 5, 3, 4, 0 };
 5    var sum: i32 = 0;
 6
 7    // For loops iterate over slices and arrays.
 8    for (items) |value| {
 9        // Break and continue are supported.
10        if (value == 0) {
11            continue;
12        }
13        sum += value;
14    }
15    try expect(sum == 16);
16
17    // To iterate over a portion of a slice, reslice.
18    for (items[0..1]) |value| {
19        sum += value;
20    }
21    try expect(sum == 20);
22
23    // To access the index of iteration, specify a second condition as well
24    // as a second capture value.
25    var sum2: i32 = 0;
26    for (items, 0..) |_, i| {
27        try expect(@TypeOf(i) == usize);
28        sum2 += @as(i32, @intCast(i));
29    }
30    try expect(sum2 == 10);
31
32    // To iterate over consecutive integers, use the range syntax.
33    // Unbounded range is always a compile error.
34    var sum3: usize = 0;
35    for (0..5) |i| {
36        sum3 += i;
37    }
38    try expect(sum3 == 10);
39}
40
41test "multi object for" {
42    const items = [_]usize{ 1, 2, 3 };
43    const items2 = [_]usize{ 4, 5, 6 };
44    var count: usize = 0;
45
46    // Iterate over multiple objects.
47    // All lengths must be equal at the start of the loop, otherwise detectable
48    // illegal behavior occurs.
49    for (items, items2) |i, j| {
50        count += i + j;
51    }
52
53    try expect(count == 21);
54}
55
56test "for reference" {
57    var items = [_]i32{ 3, 4, 2 };
58
59    // Iterate over the slice by reference by
60    // specifying that the capture value is a pointer.
61    for (&items) |*value| {
62        value.* += 1;
63    }
64
65    try expect(items[0] == 4);
66    try expect(items[1] == 5);
67    try expect(items[2] == 3);
68}
69
70test "for else" {
71    // For allows an else attached to it, the same as a while loop.
72    const items = [_]?i32{ 3, 4, null, 5 };
73
74    // For loops can also be used as expressions.
75    // Similar to while loops, when you break from a for loop, the else branch is not evaluated.
76    var sum: i32 = 0;
77    const result = for (items) |value| {
78        if (value != null) {
79            sum += value.?;
80        }
81    } else blk: {
82        try expect(sum == 12);
83        break :blk sum;
84    };
85    try expect(result == 12);
86}
87
88// test