循环语句 #
一、while 循环 #
1.1 基本 while 循环 #
zig
const std = @import("std");
pub fn main() void {
var i: usize = 0;
while (i < 5) {
std.debug.print("i = {}\n", .{i});
i += 1;
}
}
1.2 while 带继续表达式 #
zig
const std = @import("std");
pub fn main() void {
var i: usize = 0;
while (i < 5) : (i += 1) {
std.debug.print("i = {}\n", .{i});
}
}
1.3 while 表达式 #
while 可以作为表达式使用:
zig
const std = @import("std");
pub fn main() void {
var sum: i32 = 0;
var i: i32 = 1;
const result = while (i <= 10) : (i += 1) {
sum += i;
if (i == 5) break sum;
} else 0;
std.debug.print("Result: {}\n", .{result});
}
1.4 while 与可选类型 #
zig
const std = @import("std");
var items = [_]?i32{ 1, 2, null, 4, 5 };
var index: usize = 0;
fn nextItem() ?i32 {
if (index >= items.len) return null;
const item = items[index];
index += 1;
return item;
}
pub fn main() void {
index = 0;
while (nextItem()) |item| {
std.debug.print("Item: {}\n", .{item});
}
}
1.5 while 与错误联合类型 #
zig
const std = @import("std");
fn mayFail() !i32 {
return 42;
}
pub fn main() void {
var attempts: u32 = 0;
while (mayFail()) |value| {
std.debug.print("Got: {}\n", .{value});
attempts += 1;
if (attempts >= 3) break;
} else |err| {
std.debug.print("Error: {}\n", .{err});
}
}
二、for 循环 #
2.1 基本 for 循环 #
zig
const std = @import("std");
pub fn main() void {
const items = [_]i32{ 10, 20, 30, 40, 50 };
for (items) |item| {
std.debug.print("Item: {}\n", .{item});
}
}
2.2 带索引的 for 循环 #
zig
const std = @import("std");
pub fn main() void {
const items = [_]i32{ 10, 20, 30, 40, 50 };
for (items, 0..) |item, i| {
std.debug.print("items[{}] = {}\n", .{ i, item });
}
}
2.3 修改元素 #
zig
const std = @import("std");
pub fn main() void {
var items = [_]i32{ 1, 2, 3, 4, 5 };
for (&items) |*item| {
item.* *= 2;
}
std.debug.print("Modified: {any}\n", .{items});
}
2.4 多数组遍历 #
zig
const std = @import("std");
pub fn main() void {
const names = [_][]const u8{ "Alice", "Bob", "Charlie" };
const ages = [_]u8{ 25, 30, 35 };
for (names, ages) |name, age| {
std.debug.print("{s} is {} years old\n", .{ name, age });
}
}
2.5 for 表达式 #
zig
const std = @import("std");
pub fn main() void {
const items = [_]i32{ 1, 2, 3, 4, 5 };
const found = for (items) |item| {
if (item == 3) break true;
} else false;
std.debug.print("Found 3: {}\n", .{found});
}
2.6 for 与切片 #
zig
const std = @import("std");
pub fn main() void {
var arr = [_]i32{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
const slice = arr[2..7];
for (slice, 0..) |item, i| {
std.debug.print("slice[{}] = {}\n", .{ i, item });
}
}
三、循环控制 #
3.1 break #
zig
const std = @import("std");
pub fn main() void {
var i: usize = 0;
while (i < 10) : (i += 1) {
if (i == 5) break;
std.debug.print("i = {}\n", .{i});
}
std.debug.print("Loop ended at i = {}\n", .{i});
}
3.2 continue #
zig
const std = @import("std");
pub fn main() void {
for (0..10) |i| {
if (i % 2 == 0) continue;
std.debug.print("Odd: {}\n", .{i});
}
}
3.3 标签 #
zig
const std = @import("std");
pub fn main() void {
outer: for (0..3) |i| {
for (0..3) |j| {
if (i == 1 and j == 1) break :outer;
std.debug.print("i={}, j={}\n", .{ i, j });
}
}
std.debug.print("Done\n", .{});
}
3.4 带值的 break #
zig
const std = @import("std");
pub fn main() void {
const items = [_]i32{ 1, 2, 3, 4, 5 };
const result = blk: for (items) |item| {
if (item == 3) break :blk item * 10;
} else 0;
std.debug.print("Result: {}\n", .{result});
}
四、inline 循环 #
4.1 inline while #
zig
const std = @import("std");
pub fn main() void {
comptime var i: usize = 0;
inline while (i < 5) : (i += 1) {
std.debug.print("i = {}\n", .{i});
}
}
4.2 inline for #
zig
const std = @import("std");
pub fn main() void {
const types = [_]type{ i8, i16, i32, i64 };
inline for (types) |T| {
std.debug.print("{} size: {}\n", .{ T, @sizeOf(T) });
}
}
4.3 inline 的用途 #
inline 循环在编译时展开,适用于:
- 类型迭代
- 编译时计算
- 生成代码
zig
const std = @import("std");
fn printTuple(tuple: anytype) void {
const fields = @typeInfo(@TypeOf(tuple)).@"struct".fields;
inline for (fields, 0..) |field, i| {
std.debug.print("field[{}] = {} (type: {})\n", .{
i,
@field(tuple, field.name),
field.type,
});
}
}
pub fn main() void {
const my_tuple = .{ 42, "hello", 3.14 };
printTuple(my_tuple);
}
五、循环表达式 #
5.1 while 表达式 #
zig
const std = @import("std");
pub fn main() void {
var i: usize = 0;
const sum = while (i < 5) : (i += 1) blk: {
if (i == 3) break :blk i * 10;
} else 0;
std.debug.print("Sum: {}\n", .{sum});
}
5.2 for 表达式 #
zig
const std = @import("std");
pub fn main() void {
const items = [_]i32{ 1, 2, 3, 4, 5 };
const doubled = blk: {
var result: [5]i32 = undefined;
for (items, 0..) |item, i| {
result[i] = item * 2;
}
break :blk result;
};
std.debug.print("Doubled: {any}\n", .{doubled});
}
六、实战示例 #
6.1 斐波那契数列 #
zig
const std = @import("std");
fn fibonacci(n: usize) usize {
if (n <= 1) return n;
var a: usize = 0;
var b: usize = 1;
var i: usize = 2;
while (i <= n) : (i += 1) {
const temp = a + b;
a = b;
b = temp;
}
return b;
}
pub fn main() void {
for (0..15) |i| {
std.debug.print("fib({}) = {}\n", .{ i, fibonacci(i) });
}
}
6.2 查找元素 #
zig
const std = @import("std");
fn findIndex(haystack: []const i32, needle: i32) ?usize {
for (haystack, 0..) |item, i| {
if (item == needle) return i;
}
return null;
}
pub fn main() void {
const arr = [_]i32{ 10, 20, 30, 40, 50 };
if (findIndex(&arr, 30)) |i| {
std.debug.print("Found at index: {}\n", .{i});
} else {
std.debug.print("Not found\n", .{});
}
}
6.3 矩阵乘法 #
zig
const std = @import("std");
fn matrixMultiply(a: [3][3]i32, b: [3][3]i32) [3][3]i32 {
var result: [3][3]i32 = undefined;
for (0..3) |i| {
for (0..3) |j| {
var sum: i32 = 0;
for (0..3) |k| {
sum += a[i][k] * b[k][j];
}
result[i][j] = sum;
}
}
return result;
}
pub fn main() void {
const a = [3][3]i32{
.{ 1, 2, 3 },
.{ 4, 5, 6 },
.{ 7, 8, 9 },
};
const b = [3][3]i32{
.{ 1, 0, 0 },
.{ 0, 1, 0 },
.{ 0, 0, 1 },
};
const result = matrixMultiply(a, b);
for (result) |row| {
std.debug.print("{any}\n", .{row});
}
}
6.4 字符串处理 #
zig
const std = @import("std");
fn countWords(text: []const u8) usize {
var count: usize = 0;
var in_word = false;
for (text) |c| {
if (c == ' ' or c == '\n' or c == '\t') {
in_word = false;
} else if (!in_word) {
in_word = true;
count += 1;
}
}
return count;
}
pub fn main() void {
const text = "Hello, world! This is a test.";
const word_count = countWords(text);
std.debug.print("Word count: {}\n", .{word_count});
}
七、最佳实践 #
7.1 选择合适的循环 #
zig
// 已知迭代次数:使用 for
for (0..10) |i| {
std.debug.print("{}\n", .{i});
}
// 条件迭代:使用 while
var i: usize = 0;
while (someCondition()) {
i += 1;
}
fn someCondition() bool {
return true;
}
7.2 避免无限循环 #
zig
// 好:有明确的终止条件
var i: usize = 0;
while (i < max_iterations) : (i += 1) {
if (found()) break;
}
// 避免:可能无限循环
while (true) {
if (found()) break;
}
fn found() bool {
return true;
}
7.3 使用标签提高可读性 #
zig
// 好:清晰的标签
search: for (items) |item| {
for (item.subitems) |subitem| {
if (subitem.match()) {
break :search;
}
}
}
// 避免:复杂的 break 逻辑
for (items) |item| {
var found = false;
for (item.subitems) |subitem| {
if (subitem.match()) {
found = true;
break;
}
}
if (found) break;
}
八、总结 #
循环语句要点:
| 类型 | 用途 |
|---|---|
| while | 条件循环 |
| for | 迭代循环 |
| inline | 编译时展开 |
| break | 跳出循环 |
| continue | 继续下一次 |
| 标签 | 控制嵌套循环 |
下一步,让我们学习循环控制!
最后更新:2026-03-27