Ziglings 笔记 15: 现代化的 For 循环

遍历的艺术

在深入学习了功能强大的 while 之后,Ziglings 的第 15 个练习向我展示了 Zig 的另一面:for 循环

如果你习惯了 C 语言的 for (i=0; i<n; i++),你会发现 Zig 的 for 完全不同。它不是用来“数数”的(至少不完全是),它是用来遍历数据的。

挑战:剧情演绎

我们有一个包含字符数组的故事线 ['h', 'h', 's', 'n', 'h'],需要通过遍历它,根据不同的字符打印出对应的表情符号(快乐、悲伤、中立)。

解决方案

这是使用 Zig for 循环的实现方式:

const std = @import("std");

pub fn main() void {
    const story = [_]u8{ 'h', 'h', 's', 'n', 'h' };

    std.debug.print("A Dramatic Story: ", .{});

    // 核心语法:for (数组) |元素|
    // 这种 |variable| 的写法在 Zig 中被称为“捕获”
    for (story) |scene| {
        if (scene == 'h') std.debug.print(":-)  ", .{});
        if (scene == 's') std.debug.print(":-(  ", .{});
        if (scene == 'n') std.debug.print(":-|  ", .{});
    }

    std.debug.print("The End.\n", .{});
}

核心知识点总结

1. 语义上的“For Each”

Zig 的 for 循环本质上就是 Foreach。

  • for (items):指定要遍历的目标。
  • |item|:定义当前元素的别名。

这种设计消除了“数组越界”的风险,因为你不需要手动管理索引 i

2. 捕获语法 (Payload Capture)

管道符 |...| 在 Zig 中随处可见(在 ifswitchcatch 中都会用到)。在这里,它把数组中的当前值“捕获”并赋值给 scene 变量。

3. 进阶预告

虽然这个练习只展示了值的遍历,但 Zig 的 for 循环其实非常灵活。在较新的 Zig 版本中,它还支持范围迭代(Range Iteration),例如 for (0..10) |i|,这完美替代了 C 语言的老式循环。


后续预告:如果不光想要元素的值,还想要元素的索引(Index)该怎么办?下一篇我们将学习如何在 for 循环中同时捕获这两者。