const expectEqual = @import("std").testing.expectEqual; test "for basics" { const items = [_]i32{ 4, 5, 3, 4, 0 }; var sum: i32 = 0; // For loops iterate over slices and arrays. for (items) |value| { // Break and continue are supported. if (value == 0) { continue; } sum += value; } try expectEqual(16, sum); // To iterate over a portion of a slice, reslice. for (items[0..1]) |value| { sum += value; } try expectEqual(20, sum); // To access the index of iteration, specify a second condition as well // as a second capture value. var sum2: i32 = 0; for (items, 0..) |_, i| { try expectEqual(usize, @TypeOf(i)); sum2 += @as(i32, @intCast(i)); } try expectEqual(10, sum2); // To iterate over consecutive integers, use the range syntax. // Unbounded range is always a compile error. var sum3: usize = 0; for (0..5) |i| { sum3 += i; } try expectEqual(10, sum3); } test "multi object for" { const items = [_]usize{ 1, 2, 3 }; const items2 = [_]usize{ 4, 5, 6 }; var count: usize = 0; // Iterate over multiple objects. // All lengths must be equal at the start of the loop, otherwise detectable // illegal behavior occurs. for (items, items2) |i, j| { count += i + j; } try expectEqual(21, count); } test "for reference" { var items = [_]i32{ 3, 4, 2 }; // Iterate over the slice by reference by // specifying that the capture value is a pointer. for (&items) |*value| { value.* += 1; } try expectEqual(4, items[0]); try expectEqual(5, items[1]); try expectEqual(3, items[2]); } test "for else" { // For allows an else attached to it, the same as a while loop. const items = [_]?i32{ 3, 4, null, 5 }; // For loops can also be used as expressions. // Similar to while loops, when you break from a for loop, the else branch is not evaluated. var sum: i32 = 0; const result = for (items) |value| { if (value != null) { sum += value.?; } } else blk: { try expectEqual(12, sum); break :blk sum; }; try expectEqual(12, result); } // test