编译时计算 #

一、comptime 基础 #

1.1 编译时变量 #

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});
    }
}

1.2 编译时常量 #

zig
const std = @import("std");

pub fn main() void {
    const factorial_5 = comptime factorial(5);
    std.debug.print("5! = {}\n", .{factorial_5});
}

fn factorial(n: u32) u32 {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

1.3 comptime 块 #

zig
const std = @import("std");

pub fn main() void {
    const result = comptime blk: {
        var sum: u32 = 0;
        var i: u32 = 1;
        while (i <= 10) : (i += 1) {
            sum += i;
        }
        break :blk sum;
    };
    
    std.debug.print("Sum 1-10 = {}\n", .{result});
}

二、comptime 参数 #

2.1 类型参数 #

zig
const std = @import("std");

fn printType(comptime T: type) void {
    std.debug.print("Type: {}\n", .{T});
    std.debug.print("Size: {}\n", .{@sizeOf(T)});
}

pub fn main() void {
    printType(i32);
    printType(f64);
    printType(bool);
}

2.2 泛型函数 #

zig
const std = @import("std");

fn max(comptime T: type, a: T, b: T) T {
    return if (a > b) a else b;
}

pub fn main() void {
    std.debug.print("max(i32, 10, 20) = {}\n", .{max(i32, 10, 20)});
    std.debug.print("max(f64, 3.14, 2.71) = {d}\n", .{max(f64, 3.14, 2.71)});
}

三、类型反射 #

3.1 @typeInfo #

zig
const std = @import("std");

fn describeType(comptime T: type) void {
    const info = @typeInfo(T);
    
    switch (info) {
        .int => |int_info| {
            std.debug.print("Integer: {} bits, signed={}\n", .{
                int_info.bits,
                int_info.signedness == .signed,
            });
        },
        .float => |float_info| {
            std.debug.print("Float: {} bits\n", .{float_info.bits});
        },
        .bool => {
            std.debug.print("Boolean\n", .{});
        },
        .@"struct" => |struct_info| {
            std.debug.print("Struct with {} fields\n", .{struct_info.fields.len});
        },
        else => {
            std.debug.print("Other type\n", .{});
        },
    }
}

const Point = struct {
    x: f32,
    y: f32,
};

pub fn main() void {
    describeType(i32);
    describeType(f64);
    describeType(bool);
    describeType(Point);
}

3.2 遍历结构体字段 #

zig
const std = @import("std");

const Person = struct {
    name: []const u8,
    age: u32,
    active: bool,
};

fn printStruct(value: anytype) void {
    const T = @TypeOf(value);
    const info = @typeInfo(T).@"struct";
    
    inline for (info.fields) |field| {
        std.debug.print("{s}: {}\n", .{
            field.name,
            @field(value, field.name),
        });
    }
}

pub fn main() void {
    const person = Person{
        .name = "Alice",
        .age = 30,
        .active = true,
    };
    
    printStruct(person);
}

四、泛型数据结构 #

4.1 泛型向量 #

zig
const std = @import("std");

fn Vec(comptime T: type, comptime n: usize) type {
    return struct {
        data: [n]T,
        
        const Self = @This();
        
        fn init(values: [n]T) Self {
            return .{ .data = values };
        }
        
        fn add(self: Self, other: Self) Self {
            var result: [n]T = undefined;
            inline for (self.data, other.data, 0..) |a, b, i| {
                result[i] = a + b;
            }
            return .{ .data = result };
        }
        
        fn dot(self: Self, other: Self) T {
            var sum: T = 0;
            inline for (self.data, other.data) |a, b| {
                sum += a * b;
            }
            return sum;
        }
    };
}

pub fn main() void {
    const v1 = Vec(f32, 3).init(.{ 1, 2, 3 });
    const v2 = Vec(f32, 3).init(.{ 4, 5, 6 });
    
    const sum = v1.add(v2);
    const dot = v1.dot(v2);
    
    std.debug.print("Sum: {any}\n", .{sum.data});
    std.debug.print("Dot: {d}\n", .{dot});
}

五、总结 #

comptime 要点:

特性 说明
comptime var 编译时变量
comptime 块 编译时执行
comptime 参数 编译时确定
@typeInfo 类型反射

下一步,让我们学习构建系统!

最后更新:2026-03-27