解答5: 制御フローの完全理解
概要
この解答では、Zigの制御フロー構文について学びます。if式、switch式、while/forループを実践的に理解します。
Part 1: if式
const std = @import("std");
pub fn ifExpressionDemo() void {
const x: i32 = 10;
// if は式として値を返せる
const description = if (x > 0) "positive" else if (x < 0) "negative" else "zero";
std.debug.print("Number is: {s}\n", .{description});
// オプショナルのアンラップ
const maybe_val: ?i32 = 42;
if (maybe_val) |val| {
std.debug.print("Value: {}\n", .{val});
}
}
Part 2: switch式
const std = @import("std");
const Color = enum { red, green, blue };
fn colorToRgb(color: Color) struct { r: u8, g: u8, b: u8 } {
return switch (color) {
.red => .{ .r = 255, .g = 0, .b = 0 },
.green => .{ .r = 0, .g = 255, .b = 0 },
.blue => .{ .r = 0, .g = 0, .b = 255 },
};
}
fn classifyChar(c: u8) []const u8 {
return switch (c) {
'a'...'z' => "lowercase",
'A'...'Z' => "uppercase",
'0'...'9' => "digit",
else => "other",
};
}
Part 3: ループ
const std = @import("std");
pub fn loopDemo() void {
// while ループ
var i: u32 = 0;
while (i < 5) : (i += 1) {
std.debug.print("i = {}\n", .{i});
}
// for ループ
const items = [_]i32{ 10, 20, 30 };
for (items, 0..) |item, idx| {
std.debug.print("items[{}] = {}\n", .{idx, item});
}
// ラベル付きブレーク
const result = blk: {
var sum: i32 = 0;
for (0..10) |n| {
sum += @intCast(n);
if (sum > 20) break :blk sum;
}
break :blk sum;
};
std.debug.print("Result: {}\n", .{result});
}
ポイント解説
- 式としての構文: if、switch、whileは値を返せる
- キャプチャ構文: オプショナルやエラーをパターンマッチで取り出せる
- 網羅性チェック: switchは全ケースをカバーする必要がある
よくある間違い
// 無限ループ!i += 1 を忘れている
var i: u32 = 0;
while (i < 10) {
// i += 1; が必要
}
// 正しい形式
while (i < 10) : (i += 1) {
// 処理
}