Ziglings 笔记 31: Switch 也是表达式
能返回值的 Switch
在上一篇笔记中,我们用 switch 来决定执行哪个打印语句。在 Ziglings 的第 31 个练习中,我们探索了 switch 更强大的形态——表达式 (Expression)。
在 C 语言中,我们通常需要这样写:
char c;
switch (val) {
case 1: c = 'A'; break;
case 2: c = 'B'; break;
// ...
}
这种写法需要先定义变量,再在每个 case 里赋值,非常啰嗦且容易出错(比如忘了 break)。
挑战:直接转换
任务是将数字数组转换为字符并打印。我们需要在 switch 中直接完成“数字 -> 字符”的映射,并把结果赋给常量 real_char。
解决方案
这是利用 Switch 表达式的代码:
const std = @import("std");
pub fn main() void {
const lang_chars = [_]u8{ 26, 9, 7, 42 };
for (lang_chars) |c| {
// 核心亮点:
// switch 块的结果直接被赋值给了 real_char。
// 这要求所有分支返回的数据类型必须一致。
const real_char: u8 = switch (c) {
1 => 'A',
2 => 'B',
3 => 'C',
4 => 'D',
5 => 'E',
6 => 'F',
7 => 'G',
8 => 'H',
9 => 'I',
10 => 'J',
// ... 省略 ...
25 => 'Y',
26 => 'Z',
// 必须处理所有情况,对于未知的数字(如 42),返回感叹号
else => '!',
};
// 注意这里使用 {c} 来打印字符,而不是数字
std.debug.print("{c}", .{real_char});
}
std.debug.print("\n", .{});
}
核心知识点总结
1. 表达式 vs 语句
当 switch 被用作表达式时,它变得像函数调用一样,会产生一个返回值。
这种写法不仅简洁,还更安全:因为 real_char 是 const(常量),Zig 保证了它一旦初始化就不会被修改。而在 C 语言的写法中,我们被迫使用可变的变量。
2. 格式说明符 {c}
在 Zig 中,u8 既是字节也是字符。
std.debug.print("{}", .{'A'});会输出65。std.debug.print("{c}", .{'A'});会输出A。 这个细节时刻提醒我们:在底层,字符依然只是数字。
后续预告:我们已经见识了 switch 的强大。但有时候我们可能会写出一些“逻辑上永远不可能发生”的分支。Zig 提供了一个特殊的关键字 unreachable 来处理这种情况。下一篇我们将深入探讨它。