在 Zig 语言中,函数(Function)是代码的基本组织单元。Zig 提供了一套强大的函数机制,包括 函数参数、返回值、泛型函数、匿名函数、内联函数 等。本文将详细讲解 Zig 的函数特性,并配以示例代码。


📖 目录

  1. 函数定义与调用
  2. 函数参数与返回值
  3. 省略返回类型(推断返回值)
  4. 匿名函数
  5. 泛型函数(comptime 参数)
  6. 内联函数(inline)
  7. 错误处理函数
  8. 参考资料

1. 函数定义与调用

在 Zig 中,函数使用 fn 关键字定义,返回值类型在参数列表后面指定。

🔹 基本语法

fn add(a: i32, b: i32) i32 {
    return a + b;
}

const std = @import("std");

pub fn main() void {
    const result = add(10, 20);
    std.debug.print("Result: {}\n", .{result}); // 输出: 30
}

  • fn add(a: i32, b: i32) i32:定义 add 函数,接受两个 i32 类型参数,并返回 i32
  • return a + b;:返回两数之和。
  • const result = add(10, 20);:调用函数,并将返回值赋给变量。

2. 函数参数与返回值

Zig 要求函数参数和返回值的类型必须明确指定(除非使用类型推断)。

🔹 多个参数

fn multiply(a: i32, b: i32, c: i32) i32 {
    return a * b * c;
}

pub fn main() void {
    std.debug.print("Multiply: {}\n", .{multiply(2, 3, 4)}); // 输出: 24
}


3. 省略返回类型(推断返回值)

在 Zig 中,如果返回值的类型可以通过 return 语句推断出来,就可以省略返回类型。

fn square(x: i32) {
    return x * x;
}

pub fn main() void {
    std.debug.print("Square: {}\n", .{square(5)}); // 输出: 25
}

注意:如果省略返回类型,但没有 return,函数的返回类型默认为 void


4. 匿名函数

匿名函数是没有名字的函数,通常用于回调或即时计算。

const std = @import("std");

pub fn main() void {
    const square = struct {
        pub fn call(x: i32) i32 {
            return x * x;
        }
    }.call;

    std.debug.print("Square: {}\n", .{square(6)}); // 输出: 36
}

这里,匿名结构体 struct{} 作为闭包,定义了 call 方法,并立即调用。


5. 泛型函数(comptime 参数)

Zig 支持 comptime 关键字,实现泛型编程。

🔹 comptime 泛型函数

fn add(comptime T: type, a: T, b: T) T {
    return a + b;
}

pub fn main() void {
    std.debug.print("Int Add: {}\n", .{add(i32, 10, 20)}); // 30
    std.debug.print("Float Add: {}\n", .{add(f64, 1.5, 2.5)}); // 4.0
}

  • comptime T: type:表示 T 是编译期类型参数。
  • add(i32, 10, 20):实例化 Ti32,执行整数加法。
  • add(f64, 1.5, 2.5):实例化 Tf64,执行浮点数加法。

6. 内联函数(inline)

内联函数是 inline fn,可用于减少函数调用开销。

🔹 使用 inline 优化

inline fn add(a: i32, b: i32) i32 {
    return a + b;
}

pub fn main() void {
    std.debug.print("Inline Add: {}\n", .{add(2, 3)}); // 5
}

inline 的作用

  1. 减少函数调用开销,直接替换为代码块,提高执行效率。
  2. 适用于小型、高频调用的函数

7. 错误处理函数

Zig 使用 ! 处理错误,例如 !T 表示函数可能返回 T 或错误值。

🔹 返回错误

const std = @import("std");

fn divide(a: i32, b: i32) !i32 {
    if (b == 0) {
        return error.DivideByZero;
    }
    return a / b;
}

pub fn main() void {
    const result = divide(10, 0) catch |err| {
        std.debug.print("Error: {}\n", .{err});
        return;
    };
    std.debug.print("Result: {}\n", .{result});
}

解释

  • fn divide(a: i32, b: i32) !i32:返回 i32error.DivideByZero
  • catch |err| 处理错误,如果 b == 0,返回错误,否则计算 a / b

8. 参考资料