错误处理 (Errors)

Zig 的错误处理旨在明确、健壮且易于使用。它不使用异常(Exceptions),而是将错误视为值。

错误集 (Error Set)

错误集类似于枚举,但专门用于定义错误。

const FileOpenError = error{
    AccessDenied,
    OutOfMemory,
    FileNotFound,
};

错误联合 (Error Union)

错误联合类型 E!T 表示一个值可能是类型 E 的错误,也可能是类型 T 的成功值。

const AllocationError = error{OutOfMemory};

test "coerce error to error union" {
    const err: AllocationError!u8 = AllocationError.OutOfMemory;
    _ = err;
}

catch

catch 运算符用于处理错误。如果左侧的表达式计算结果为错误,则执行右侧的表达式。

const number = parseNumber("123") catch 0;

catch 还可以捕获错误值:

parseNumber("invalid") catch |err| {
    std.debug.print("Error: {}\n", .{err});
    return;
};

try

try xx catch |err| return err 的简写形式。它用于将错误向上传播给调用者。

fn doSomething() !void {
    const file = try std.fs.cwd().openFile("test.txt", .{});
    defer file.close();
    // ...
}

errdefer

errdefer 语句仅在函数返回错误时执行。这对于资源清理非常有用。

fn createFoo() !*Foo {
    const foo = try allocator.create(Foo);
    errdefer allocator.destroy(foo);

    try foo.init(); // 如果这里失败,foo 将被销毁
    return foo;
}

全局错误集 (The Global Error Set)

Zig 有一个全局错误集,包含程序中定义的所有错误。错误集可以自动推断。

错误返回跟踪 (Error Return Traces)

Zig 支持错误返回跟踪,这有助于调试。当错误发生并被传播时,Zig 会记录跟踪信息。

另请参阅: