循环控制 #
一、break 语句 #
1.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\n", .{});
}
1.2 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;
}
break :blk 0;
};
std.debug.print("Result: {}\n", .{result});
}
1.3 while 表达式中的 break #
zig
const std = @import("std");
pub fn main() void {
var i: usize = 0;
const result = while (i < 10) : (i += 1) {
if (i == 5) break i * 2;
} else 0;
std.debug.print("Result: {}\n", .{result});
}
1.4 for 表达式中的 break #
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: {}\n", .{found});
}
二、continue 语句 #
2.1 基本 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});
}
}
2.2 while 中的 continue #
zig
const std = @import("std");
pub fn main() void {
var i: usize = 0;
while (i < 10) : (i += 1) {
if (i % 3 == 0) continue;
std.debug.print("Not divisible by 3: {}\n", .{i});
}
}
2.3 continue 与继续表达式 #
zig
const std = @import("std");
pub fn main() void {
var i: usize = 0;
while (i < 10) : (i += 1) {
if (i == 5) {
std.debug.print("Skipping 5\n", .{});
continue;
}
std.debug.print("i = {}\n", .{i});
}
}
三、标签 #
3.1 定义标签 #
标签用于标识循环或块:
zig
const std = @import("std");
pub fn main() void {
outer: for (0..3) |i| {
inner: for (0..3) |j| {
std.debug.print("i={}, j={}\n", .{ i, j });
}
}
}
3.2 标签 break #
zig
const std = @import("std");
pub fn main() void {
outer: for (0..3) |i| {
for (0..3) |j| {
if (i == 1 and j == 1) {
std.debug.print("Breaking outer loop\n", .{});
break :outer;
}
std.debug.print("i={}, j={}\n", .{ i, j });
}
}
std.debug.print("Done\n", .{});
}
3.3 标签 continue #
zig
const std = @import("std");
pub fn main() void {
outer: for (0..3) |i| {
for (0..3) |j| {
if (j == 1) continue :outer;
std.debug.print("i={}, j={}\n", .{ i, j });
}
}
}
3.4 块标签 #
zig
const std = @import("std");
pub fn main() void {
const result = calculate: {
var sum: i32 = 0;
for (0..10) |i| {
sum += @intCast(i);
}
break :calculate sum;
};
std.debug.print("Result: {}\n", .{result});
}
四、嵌套循环控制 #
4.1 搜索示例 #
zig
const std = @import("std");
const Item = struct {
id: u32,
value: i32,
};
const Container = struct {
items: []const Item,
};
fn findValue(containers: []const Container, target: i32) ?u32 {
search: for (containers) |container| {
for (container.items) |item| {
if (item.value == target) {
break :search item.id;
}
}
} else return null;
return null;
}
pub fn main() void {
const items1 = [_]Item{
.{ .id = 1, .value = 10 },
.{ .id = 2, .value = 20 },
};
const items2 = [_]Item{
.{ .id = 3, .value = 30 },
.{ .id = 4, .value = 40 },
};
const containers = [_]Container{
.{ .items = &items1 },
.{ .items = &items2 },
};
if (findValue(&containers, 30)) |id| {
std.debug.print("Found item with id: {}\n", .{id});
} else {
std.debug.print("Not found\n", .{});
}
}
4.2 矩阵搜索 #
zig
const std = @import("std");
fn findInMatrix(matrix: []const []const i32, target: i32) ?struct { row: usize, col: usize } {
for (matrix, 0..) |row, i| {
for (row, 0..) |val, j| {
if (val == target) {
return .{ .row = i, .col = j };
}
}
}
return null;
}
pub fn main() void {
const row1 = [_]i32{ 1, 2, 3 };
const row2 = [_]i32{ 4, 5, 6 };
const row3 = [_]i32{ 7, 8, 9 };
const matrix = [_][]const i32{ &row1, &row2, &row3 };
if (findInMatrix(&matrix, 5)) |pos| {
std.debug.print("Found at ({}, {})\n", .{ pos.row, pos.col });
} else {
std.debug.print("Not found\n", .{});
}
}
五、实战示例 #
5.1 跳过无效数据 #
zig
const std = @import("std");
const Record = struct {
id: u32,
name: []const u8,
valid: bool,
};
fn processRecords(records: []const Record) void {
process: for (records) |record| {
if (!record.valid) {
std.debug.print("Skipping invalid record: {}\n", .{record.id});
continue :process;
}
std.debug.print("Processing record {}: {s}\n", .{ record.id, record.name });
}
}
pub fn main() void {
const records = [_]Record{
.{ .id = 1, .name = "Alice", .valid = true },
.{ .id = 2, .name = "Bob", .valid = false },
.{ .id = 3, .name = "Charlie", .valid = true },
.{ .id = 4, .name = "Diana", .valid = false },
};
processRecords(&records);
}
5.2 限制迭代次数 #
zig
const std = @import("std");
fn processWithLimit(items: []const i32, max_iterations: usize) void {
var count: usize = 0;
for (items) |item| {
if (count >= max_iterations) {
std.debug.print("Reached limit of {} iterations\n", .{max_iterations});
break;
}
std.debug.print("Processing: {}\n", .{item});
count += 1;
}
}
pub fn main() void {
const items = [_]i32{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
processWithLimit(&items, 5);
}
5.3 重试逻辑 #
zig
const std = @import("std");
fn tryOperation() !void {
return error.TemporaryFailure;
}
fn withRetry(max_attempts: u32) !void {
var attempts: u32 = 0;
while (attempts < max_attempts) : (attempts += 1) {
tryOperation() catch |err| {
std.debug.print("Attempt {} failed: {}\n", .{ attempts + 1, err });
continue;
};
std.debug.print("Success on attempt {}\n", .{attempts + 1});
return;
}
return error.MaxRetriesExceeded;
}
pub fn main() void {
withRetry(3) catch |err| {
std.debug.print("Operation failed: {}\n", .{err});
};
}
5.4 状态机处理 #
zig
const std = @import("std");
const State = enum {
start,
reading,
processing,
done,
error,
};
fn processStateMachine() void {
var state: State = .start;
var data: []const u8 = "test data";
var processed: usize = 0;
state_machine: while (true) {
switch (state) {
.start => {
std.debug.print("Starting...\n", .{});
state = .reading;
},
.reading => {
if (processed < data.len) {
std.debug.print("Reading byte {}\n", .{processed});
processed += 1;
state = .processing;
} else {
state = .done;
}
},
.processing => {
std.debug.print("Processing...\n", .{});
if (processed % 2 == 0) {
state = .reading;
} else {
state = .error;
}
},
.done => {
std.debug.print("Done!\n", .{});
break :state_machine;
},
.error => {
std.debug.print("Error occurred!\n", .{});
break :state_machine;
},
}
}
}
pub fn main() void {
processStateMachine();
}
六、最佳实践 #
6.1 使用有意义的标签名 #
zig
// 好
search: for (items) |item| {
for (item.subitems) |subitem| {
if (subitem.match()) break :search;
}
}
// 避免
loop1: for (items) |item| {
loop2: for (item.subitems) |subitem| {
if (subitem.match()) break :loop1;
}
}
6.2 避免过度使用 break #
zig
// 好:使用条件表达式
var found = false;
for (items) |item| {
if (item.match()) {
found = true;
break;
}
}
// 更好:使用 for 表达式
const found = for (items) |item| {
if (item.match()) break true;
} else false;
6.3 使用 continue 简化逻辑 #
zig
// 好:使用 continue
for (items) |item| {
if (!item.valid) continue;
if (item.skip) continue;
process(item);
}
// 避免:深层嵌套
for (items) |item| {
if (item.valid) {
if (!item.skip) {
process(item);
}
}
}
七、总结 #
循环控制要点:
| 语句 | 说明 |
|---|---|
| break | 跳出循环 |
| break :label | 跳出指定循环 |
| break value | 带值跳出 |
| continue | 继续下一次 |
| continue :label | 继续指定循环 |
| 标签 | 标识循环或块 |
下一步,让我们学习函数!
最后更新:2026-03-27