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

终于等到你:Range For

在 Ziglings 的第 95 个练习中,我们迎来了一个令人兴奋的语法糖:基于范围的 For 循环

在早期的 Zig 版本中,如果我们想打印 1 到 10,不得不写一个 while 循环,声明变量,然后在循环末尾手动 i += 1。这不仅啰嗦,还容易出错(比如忘了递增导致死循环)。 现在,Zig 终于支持了类似 Rust 或 Python 的范围语法。

挑战:重构数字遍历

我们需要重写之前的练习(打印 1 到 20,跳过 3 和 5 的倍数),但这次要用 for 循环来实现。

解决方案

使用 start..end 语法,注意它是左闭右开的(包含开始,不包含结束)。所以要遍历到 20,结束值必须写 21。

const std = @import("std");

pub fn main() void {
    // 语法核心:for (1..21)
    // 这将生成一个从 1 到 20 的序列。
    // |n| 是捕获的循环变量,代表当前的数字。
    for (1..21) |n| {
        
        // 遇到 3 的倍数,跳过
        if (n % 3 == 0) continue;
        
        // 遇到 5 的倍数,跳过
        if (n % 5 == 0) continue;
        
        std.debug.print("{} ", .{n});
    }

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

核心知识点总结

1. 范围语法的细节

  • 0..10: 生成 0, 1, ..., 9
  • a..b: 生成从 ab-1 的序列。
  • 如果你想包含最后一个数,必须把结束值设为 target + 1

2. usize 类型

在这个循环中,捕获变量 n 的类型默认为 usize(无符号的大小类型,取决于机器架构是 32 位还是 64 位)。这通常是作为数组索引的最佳类型。

3. 代码对比

Old Style (While):

var i: usize = 0;
while (i < 10) : (i += 1) { ... }

New Style (For):

for (0..10) |i| { ... }

显然,新的写法更加声明式,更能表达“遍历”的意图。


后续预告:我们已经掌握了基本的控制流(if, while, for)。接下来,我们要去接触 Zig 中最有特色的功能之一——函数 (Functions)。你知道 Zig 的函数参数默认是不可变的吗?下一篇见分晓。