循环控制 #

一、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