结构体方法 #

一、方法基础 #

1.1 方法定义 #

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

const Rectangle = struct {
    width: f32,
    height: f32,
    
    fn area(self: Rectangle) f32 {
        return self.width * self.height;
    }
};

pub fn main() void {
    const rect = Rectangle{ .width = 10, .height = 5 };
    std.debug.print("Area: {d}\n", .{rect.area()});
}

1.2 self 参数 #

self 参数可以是值或指针:

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

const Counter = struct {
    value: u32,
    
    // 值接收者:只读访问
    fn get(self: Counter) u32 {
        return self.value;
    }
    
    // 指针接收者:可修改
    fn increment(self: *Counter) void {
        self.value += 1;
    }
};

pub fn main() void {
    var counter = Counter{ .value = 0 };
    
    counter.increment();
    counter.increment();
    
    std.debug.print("Value: {}\n", .{counter.get()});
}

二、值接收者 #

2.1 只读方法 #

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

const Point = struct {
    x: f32,
    y: f32,
    
    fn distanceFromOrigin(self: Point) f32 {
        return @sqrt(self.x * self.x + self.y * self.y);
    }
    
    fn equals(self: Point, other: Point) bool {
        return self.x == other.x and self.y == other.y;
    }
};

pub fn main() void {
    const p1 = Point{ .x = 3, .y = 4 };
    const p2 = Point{ .x = 3, .y = 4 };
    
    std.debug.print("Distance: {d}\n", .{p1.distanceFromOrigin()});
    std.debug.print("Equals: {}\n", .{p1.equals(p2)});
}

2.2 返回新实例 #

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

const Point = struct {
    x: f32,
    y: f32,
    
    fn add(self: Point, other: Point) Point {
        return .{
            .x = self.x + other.x,
            .y = self.y + other.y,
        };
    }
    
    fn scale(self: Point, factor: f32) Point {
        return .{
            .x = self.x * factor,
            .y = self.y * factor,
        };
    }
};

pub fn main() void {
    const p1 = Point{ .x = 1, .y = 2 };
    const p2 = Point{ .x = 3, .y = 4 };
    
    const sum = p1.add(p2);
    const scaled = p1.scale(2);
    
    std.debug.print("Sum: ({}, {})\n", .{ sum.x, sum.y });
    std.debug.print("Scaled: ({}, {})\n", .{ scaled.x, scaled.y });
}

三、指针接收者 #

3.1 修改方法 #

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

const BankAccount = struct {
    balance: f32,
    
    fn deposit(self: *BankAccount, amount: f32) void {
        self.balance += amount;
    }
    
    fn withdraw(self: *BankAccount, amount: f32) bool {
        if (self.balance >= amount) {
            self.balance -= amount;
            return true;
        }
        return false;
    }
};

pub fn main() void {
    var account = BankAccount{ .balance = 100.0 };
    
    account.deposit(50.0);
    std.debug.print("After deposit: {d}\n", .{account.balance});
    
    if (account.withdraw(30.0)) {
        std.debug.print("After withdrawal: {d}\n", .{account.balance});
    }
}

3.2 链式调用 #

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

const Builder = struct {
    value: []const u8,
    
    fn append(self: *Builder, str: []const u8) *Builder {
        self.value = str;
        return self;
    }
    
    fn build(self: Builder) []const u8 {
        return self.value;
    }
};

pub fn main() void {
    var builder = Builder{ .value = "" };
    
    const result = builder.append("Hello").append(" World").build();
    std.debug.print("Result: {s}\n", .{result});
}

四、关联函数 #

4.1 构造函数 #

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

const Color = struct {
    r: u8,
    g: u8,
    b: u8,
    
    fn new(r: u8, g: u8, b: u8) Color {
        return .{ .r = r, .g = g, .b = b };
    }
    
    fn red() Color {
        return .{ .r = 255, .g = 0, .b = 0 };
    }
    
    fn green() Color {
        return .{ .r = 0, .g = 255, .b = 0 };
    }
    
    fn blue() Color {
        return .{ .r = 0, .g = 0, .b = 255 };
    }
};

pub fn main() void {
    const red = Color.red();
    const custom = Color.new(100, 150, 200);
    
    std.debug.print("Red: ({}, {}, {})\n", .{ red.r, red.g, red.b });
    std.debug.print("Custom: ({}, {}, {})\n", .{ custom.r, custom.g, custom.b });
}

4.2 工厂方法 #

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

const Parser = struct {
    input: []const u8,
    pos: usize,
    
    fn init(input: []const u8) Parser {
        return .{
            .input = input,
            .pos = 0,
        };
    }
    
    fn fromFile(path: []const u8) !Parser {
        _ = path;
        return .{
            .input = "file content",
            .pos = 0,
        };
    }
};

pub fn main() void {
    const p1 = Parser.init("hello");
    std.debug.print("Parser pos: {}\n", .{p1.pos});
}

五、方法与错误 #

5.1 返回错误 #

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

const Stack = struct {
    items: [10]i32,
    top: usize,
    
    fn push(self: *Stack, value: i32) !void {
        if (self.top >= self.items.len) {
            return error.StackFull;
        }
        self.items[self.top] = value;
        self.top += 1;
    }
    
    fn pop(self: *Stack) !i32 {
        if (self.top == 0) {
            return error.StackEmpty;
        }
        self.top -= 1;
        return self.items[self.top];
    }
};

pub fn main() !void {
    var stack = Stack{ .items = undefined, .top = 0 };
    
    try stack.push(1);
    try stack.push(2);
    
    while (stack.pop()) |value| {
        std.debug.print("Popped: {}\n", .{value});
    } else |err| {
        std.debug.print("Error: {}\n", .{err});
    }
}

六、总结 #

方法要点:

类型 语法 用途
值接收者 fn name(self: Self) 只读操作
指针接收者 fn name(self: *Self) 修改操作
关联函数 fn name() 构造、工厂

下一步,让我们学习内存管理!

最后更新:2026-03-27