Ziglings 笔记 100: 百题达成!并行遍历 (Multi-object For Loops)
里程碑:100 题达成!🎉
在 Ziglings 的第 100 个练习中,我们不仅收获了成就感,还学会了 Zig 中最让 C 程序员羡慕的特性之一:多重并行循环。
在传统的循环中,如果我们要比较两个数组,必须引入一个中间变量 i 作为索引。但在 Zig 中,我们可以直接把两个数组扔进 for 循环,就像把两条铁轨合并成一条一样自然。
挑战:真假美猴王
我们需要比较两个数组:
hex_nums: 用十六进制书写的数字。dec_nums: 用十进制书写的数字。
虽然写法不同,但在底层它们应该是一样的(例如 0xb == 11)。我们需要同时遍历它们来验证这一点。
解决方案
使用多重 for 循环语法:
const std = @import("std");
const print = std.debug.print;
pub fn main() void {
const hex_nums = [_]u8{ 0xb, 0x2a, 0x77 }; // 11, 42, 119
const dec_nums = [_]u8{ 11, 42, 119 };
// 核心语法:for (A, B) |a, b|
// Zig 会自动同步遍历这两个数组。
// hn 是 hex_nums 的当前元素,dn 是 dec_nums 的当前元素。
for (hex_nums, dec_nums) |hn, dn| {
// 比较值
if (hn != dn) {
print("Uh oh! Found a mismatch: {d} vs {d}\n", .{ hn, dn });
return;
}
}
print("Arrays match!\n", .{});
}
核心知识点总结
1. 拉链式迭代 (Zipping)
这种语法 for (a, b) 在函数式编程中通常被称为 “Zip”。它极大地提高了代码的可读性。你不需要关心当前的索引是 0 还是 100,你只关心“现在的 A 和现在的 B 是一对”。
2. 长度安全检查
Zig 对安全性有执着的追求。当你写 for (a, b) 时,Zig 隐含了一个断言:a 和 b 的长度必须相等。
如果长度不一致,在 Debug 模式下程序会直接 Panic。这防止了“一个数组遍历完了,另一个还在继续访问越界内存”的经典错误。
3. 三管齐下?
这个语法支持任意数量的数组,甚至还可以带上索引!
// 同时遍历数组 a, 数组 b, 以及索引 i
for (a, b, 0..) |v_a, v_b, i| {
// ...
}
这是 Zig 循环语法的完全体形态。
后续预告:百题之后,我们还要去哪里?Ziglings 的旅程还在继续。接下来的练习将深入更高级的主题,比如 函数指针、测试系统 (Testing) 以及 C 语言构建系统的集成。让我们继续前进!