循环语句 #

一、while 循环 #

1.1 基本 while 循环 #

zig
const std = @import("std");

pub fn main() void {
    var i: usize = 0;
    
    while (i < 5) {
        std.debug.print("i = {}\n", .{i});
        i += 1;
    }
}

1.2 while 带继续表达式 #

zig
const std = @import("std");

pub fn main() void {
    var i: usize = 0;
    
    while (i < 5) : (i += 1) {
        std.debug.print("i = {}\n", .{i});
    }
}

1.3 while 表达式 #

while 可以作为表达式使用:

zig
const std = @import("std");

pub fn main() void {
    var sum: i32 = 0;
    var i: i32 = 1;
    
    const result = while (i <= 10) : (i += 1) {
        sum += i;
        if (i == 5) break sum;
    } else 0;
    
    std.debug.print("Result: {}\n", .{result});
}

1.4 while 与可选类型 #

zig
const std = @import("std");

var items = [_]?i32{ 1, 2, null, 4, 5 };
var index: usize = 0;

fn nextItem() ?i32 {
    if (index >= items.len) return null;
    const item = items[index];
    index += 1;
    return item;
}

pub fn main() void {
    index = 0;
    
    while (nextItem()) |item| {
        std.debug.print("Item: {}\n", .{item});
    }
}

1.5 while 与错误联合类型 #

zig
const std = @import("std");

fn mayFail() !i32 {
    return 42;
}

pub fn main() void {
    var attempts: u32 = 0;
    
    while (mayFail()) |value| {
        std.debug.print("Got: {}\n", .{value});
        attempts += 1;
        if (attempts >= 3) break;
    } else |err| {
        std.debug.print("Error: {}\n", .{err});
    }
}

二、for 循环 #

2.1 基本 for 循环 #

zig
const std = @import("std");

pub fn main() void {
    const items = [_]i32{ 10, 20, 30, 40, 50 };
    
    for (items) |item| {
        std.debug.print("Item: {}\n", .{item});
    }
}

2.2 带索引的 for 循环 #

zig
const std = @import("std");

pub fn main() void {
    const items = [_]i32{ 10, 20, 30, 40, 50 };
    
    for (items, 0..) |item, i| {
        std.debug.print("items[{}] = {}\n", .{ i, item });
    }
}

2.3 修改元素 #

zig
const std = @import("std");

pub fn main() void {
    var items = [_]i32{ 1, 2, 3, 4, 5 };
    
    for (&items) |*item| {
        item.* *= 2;
    }
    
    std.debug.print("Modified: {any}\n", .{items});
}

2.4 多数组遍历 #

zig
const std = @import("std");

pub fn main() void {
    const names = [_][]const u8{ "Alice", "Bob", "Charlie" };
    const ages = [_]u8{ 25, 30, 35 };
    
    for (names, ages) |name, age| {
        std.debug.print("{s} is {} years old\n", .{ name, age });
    }
}

2.5 for 表达式 #

zig
const std = @import("std");

pub fn main() void {
    const items = [_]i32{ 1, 2, 3, 4, 5 };
    
    const found = for (items) |item| {
        if (item == 3) break true;
    } else false;
    
    std.debug.print("Found 3: {}\n", .{found});
}

2.6 for 与切片 #

zig
const std = @import("std");

pub fn main() void {
    var arr = [_]i32{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    const slice = arr[2..7];
    
    for (slice, 0..) |item, i| {
        std.debug.print("slice[{}] = {}\n", .{ i, item });
    }
}

三、循环控制 #

3.1 break #

zig
const std = @import("std");

pub fn main() void {
    var i: usize = 0;
    
    while (i < 10) : (i += 1) {
        if (i == 5) break;
        std.debug.print("i = {}\n", .{i});
    }
    
    std.debug.print("Loop ended at i = {}\n", .{i});
}

3.2 continue #

zig
const std = @import("std");

pub fn main() void {
    for (0..10) |i| {
        if (i % 2 == 0) continue;
        std.debug.print("Odd: {}\n", .{i});
    }
}

3.3 标签 #

zig
const std = @import("std");

pub fn main() void {
    outer: for (0..3) |i| {
        for (0..3) |j| {
            if (i == 1 and j == 1) break :outer;
            std.debug.print("i={}, j={}\n", .{ i, j });
        }
    }
    
    std.debug.print("Done\n", .{});
}

3.4 带值的 break #

zig
const std = @import("std");

pub fn main() void {
    const items = [_]i32{ 1, 2, 3, 4, 5 };
    
    const result = blk: for (items) |item| {
        if (item == 3) break :blk item * 10;
    } else 0;
    
    std.debug.print("Result: {}\n", .{result});
}

四、inline 循环 #

4.1 inline while #

zig
const std = @import("std");

pub fn main() void {
    comptime var i: usize = 0;
    
    inline while (i < 5) : (i += 1) {
        std.debug.print("i = {}\n", .{i});
    }
}

4.2 inline for #

zig
const std = @import("std");

pub fn main() void {
    const types = [_]type{ i8, i16, i32, i64 };
    
    inline for (types) |T| {
        std.debug.print("{} size: {}\n", .{ T, @sizeOf(T) });
    }
}

4.3 inline 的用途 #

inline 循环在编译时展开,适用于:

  • 类型迭代
  • 编译时计算
  • 生成代码
zig
const std = @import("std");

fn printTuple(tuple: anytype) void {
    const fields = @typeInfo(@TypeOf(tuple)).@"struct".fields;
    inline for (fields, 0..) |field, i| {
        std.debug.print("field[{}] = {} (type: {})\n", .{
            i,
            @field(tuple, field.name),
            field.type,
        });
    }
}

pub fn main() void {
    const my_tuple = .{ 42, "hello", 3.14 };
    printTuple(my_tuple);
}

五、循环表达式 #

5.1 while 表达式 #

zig
const std = @import("std");

pub fn main() void {
    var i: usize = 0;
    
    const sum = while (i < 5) : (i += 1) blk: {
        if (i == 3) break :blk i * 10;
    } else 0;
    
    std.debug.print("Sum: {}\n", .{sum});
}

5.2 for 表达式 #

zig
const std = @import("std");

pub fn main() void {
    const items = [_]i32{ 1, 2, 3, 4, 5 };
    
    const doubled = blk: {
        var result: [5]i32 = undefined;
        for (items, 0..) |item, i| {
            result[i] = item * 2;
        }
        break :blk result;
    };
    
    std.debug.print("Doubled: {any}\n", .{doubled});
}

六、实战示例 #

6.1 斐波那契数列 #

zig
const std = @import("std");

fn fibonacci(n: usize) usize {
    if (n <= 1) return n;
    
    var a: usize = 0;
    var b: usize = 1;
    var i: usize = 2;
    
    while (i <= n) : (i += 1) {
        const temp = a + b;
        a = b;
        b = temp;
    }
    
    return b;
}

pub fn main() void {
    for (0..15) |i| {
        std.debug.print("fib({}) = {}\n", .{ i, fibonacci(i) });
    }
}

6.2 查找元素 #

zig
const std = @import("std");

fn findIndex(haystack: []const i32, needle: i32) ?usize {
    for (haystack, 0..) |item, i| {
        if (item == needle) return i;
    }
    return null;
}

pub fn main() void {
    const arr = [_]i32{ 10, 20, 30, 40, 50 };
    
    if (findIndex(&arr, 30)) |i| {
        std.debug.print("Found at index: {}\n", .{i});
    } else {
        std.debug.print("Not found\n", .{});
    }
}

6.3 矩阵乘法 #

zig
const std = @import("std");

fn matrixMultiply(a: [3][3]i32, b: [3][3]i32) [3][3]i32 {
    var result: [3][3]i32 = undefined;
    
    for (0..3) |i| {
        for (0..3) |j| {
            var sum: i32 = 0;
            for (0..3) |k| {
                sum += a[i][k] * b[k][j];
            }
            result[i][j] = sum;
        }
    }
    
    return result;
}

pub fn main() void {
    const a = [3][3]i32{
        .{ 1, 2, 3 },
        .{ 4, 5, 6 },
        .{ 7, 8, 9 },
    };
    
    const b = [3][3]i32{
        .{ 1, 0, 0 },
        .{ 0, 1, 0 },
        .{ 0, 0, 1 },
    };
    
    const result = matrixMultiply(a, b);
    
    for (result) |row| {
        std.debug.print("{any}\n", .{row});
    }
}

6.4 字符串处理 #

zig
const std = @import("std");

fn countWords(text: []const u8) usize {
    var count: usize = 0;
    var in_word = false;
    
    for (text) |c| {
        if (c == ' ' or c == '\n' or c == '\t') {
            in_word = false;
        } else if (!in_word) {
            in_word = true;
            count += 1;
        }
    }
    
    return count;
}

pub fn main() void {
    const text = "Hello, world! This is a test.";
    const word_count = countWords(text);
    
    std.debug.print("Word count: {}\n", .{word_count});
}

七、最佳实践 #

7.1 选择合适的循环 #

zig
// 已知迭代次数:使用 for
for (0..10) |i| {
    std.debug.print("{}\n", .{i});
}

// 条件迭代:使用 while
var i: usize = 0;
while (someCondition()) {
    i += 1;
}

fn someCondition() bool {
    return true;
}

7.2 避免无限循环 #

zig
// 好:有明确的终止条件
var i: usize = 0;
while (i < max_iterations) : (i += 1) {
    if (found()) break;
}

// 避免:可能无限循环
while (true) {
    if (found()) break;
}

fn found() bool {
    return true;
}

7.3 使用标签提高可读性 #

zig
// 好:清晰的标签
search: for (items) |item| {
    for (item.subitems) |subitem| {
        if (subitem.match()) {
            break :search;
        }
    }
}

// 避免:复杂的 break 逻辑
for (items) |item| {
    var found = false;
    for (item.subitems) |subitem| {
        if (subitem.match()) {
            found = true;
            break;
        }
    }
    if (found) break;
}

八、总结 #

循环语句要点:

类型 用途
while 条件循环
for 迭代循环
inline 编译时展开
break 跳出循环
continue 继续下一次
标签 控制嵌套循环

下一步,让我们学习循环控制!

最后更新:2026-03-27