结构体基础 #

一、结构体定义 #

1.1 基本结构体 #

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

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

pub fn main() void {
    const person = Person{
        .name = "Alice",
        .age = 30,
        .active = true,
    };
    
    std.debug.print("Name: {s}\n", .{person.name});
    std.debug.print("Age: {}\n", .{person.age});
    std.debug.print("Active: {}\n", .{person.active});
}

1.2 默认值 #

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

const Config = struct {
    host: []const u8 = "localhost",
    port: u16 = 8080,
    debug: bool = false,
    timeout: u32 = 30,
};

pub fn main() void {
    const config1 = Config{};
    const config2 = Config{ .port = 3000 };
    const config3 = Config{ .host = "example.com", .debug = true };
    
    std.debug.print("Config1: {s}:{}\n", .{ config1.host, config1.port });
    std.debug.print("Config2: {s}:{}\n", .{ config2.host, config2.port });
    std.debug.print("Config3: {s}:{} (debug={})\n", .{ config3.host, config3.port, config3.debug });
}

1.3 空结构体 #

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

const Empty = struct {};

pub fn main() void {
    const e = Empty{};
    std.debug.print("Empty struct size: {}\n", .{@sizeOf(@TypeOf(e))});
}

二、结构体初始化 #

2.1 完整初始化 #

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

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

pub fn main() void {
    const p1 = Point{ .x = 10.0, .y = 20.0 };
    const p2 = Point{ .y = 20.0, .x = 10.0 };  // 顺序可以不同
    
    std.debug.print("p1: ({}, {})\n", .{ p1.x, p1.y });
    std.debug.print("p2: ({}, {})\n", .{ p2.x, p2.y });
}

2.2 部分初始化 #

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

const Rectangle = struct {
    width: f32 = 100,
    height: f32 = 100,
    color: []const u8 = "white",
};

pub fn main() void {
    const r1 = Rectangle{ .width = 200 };
    const r2 = Rectangle{ .height = 50, .color = "blue" };
    
    std.debug.print("r1: {} x {}, {s}\n", .{ r1.width, r1.height, r1.color });
    std.debug.print("r2: {} x {}, {s}\n", .{ r2.width, r2.height, r2.color });
}

2.3 使用 undefined #

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

const Buffer = struct {
    data: [100]u8,
    len: usize,
};

pub fn main() void {
    var buf: Buffer = undefined;
    buf.len = 0;
    
    std.debug.print("Buffer len: {}\n", .{buf.len});
}

三、字段访问 #

3.1 点号访问 #

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

const User = struct {
    id: u32,
    name: []const u8,
    email: []const u8,
};

pub fn main() void {
    const user = User{
        .id = 1,
        .name = "Alice",
        .email = "alice@example.com",
    };
    
    std.debug.print("User {}: {s} <{s}>\n", .{ user.id, user.name, user.email });
}

3.2 指针访问 #

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

const Counter = struct {
    value: u32,
};

fn increment(counter: *Counter) void {
    counter.value += 1;
}

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

3.3 通过 @field 动态访问 #

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

const Settings = struct {
    volume: u8 = 50,
    brightness: u8 = 100,
    contrast: u8 = 75,
};

pub fn main() void {
    var settings = Settings{};
    
    // 动态访问字段
    @field(settings, "volume") = 80;
    @field(settings, "brightness") = 90;
    
    std.debug.print("Volume: {}\n", .{@field(settings, "volume")});
    std.debug.print("Brightness: {}\n", .{@field(settings, "brightness")});
}

四、结构体方法 #

4.1 方法定义 #

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

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

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

4.2 修改方法 #

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

const Counter = struct {
    value: u32,
    
    fn increment(self: *Counter) void {
        self.value += 1;
    }
    
    fn reset(self: *Counter) void {
        self.value = 0;
    }
};

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

4.3 关联函数 #

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

const Point = struct {
    x: f32,
    y: f32,
    
    // 关联函数(无 self 参数)
    fn origin() Point {
        return .{ .x = 0, .y = 0 };
    }
    
    fn new(x: f32, y: f32) Point {
        return .{ .x = x, .y = y };
    }
    
    fn distance(self: Point, other: Point) f32 {
        const dx = self.x - other.x;
        const dy = self.y - other.y;
        return @sqrt(dx * dx + dy * dy);
    }
};

pub fn main() void {
    const origin = Point.origin();
    const p = Point.new(3, 4);
    
    std.debug.print("Origin: ({}, {})\n", .{ origin.x, origin.y });
    std.debug.print("Point: ({}, {})\n", .{ p.x, p.y });
    std.debug.print("Distance from origin: {d}\n", .{p.distance(origin)});
}

五、结构体嵌套 #

5.1 嵌套结构体 #

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

const Address = struct {
    street: []const u8,
    city: []const u8,
    country: []const u8,
};

const Person = struct {
    name: []const u8,
    address: Address,
};

pub fn main() void {
    const person = Person{
        .name = "Alice",
        .address = .{
            .street = "123 Main St",
            .city = "New York",
            .country = "USA",
        },
    };
    
    std.debug.print("{s} lives in {s}, {s}\n", .{
        person.name,
        person.address.city,
        person.address.country,
    });
}

5.2 匿名结构体 #

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

pub fn main() void {
    const point = struct {
        x: i32,
        y: i32,
    }{
        .x = 10,
        .y = 20,
    };
    
    std.debug.print("Point: ({}, {})\n", .{ point.x, point.y });
}

六、内存布局 #

6.1 默认布局 #

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

const DefaultStruct = struct {
    a: u8,
    b: u32,
    c: u8,
};

pub fn main() void {
    std.debug.print("DefaultStruct size: {}\n", .{@sizeOf(DefaultStruct)});
    std.debug.print("Field offsets: a={}, b={}, c={}\n", .{
        @offsetOf(DefaultStruct, "a"),
        @offsetOf(DefaultStruct, "b"),
        @offsetOf(DefaultStruct, "c"),
    });
}

6.2 packed 结构体 #

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

const PackedStruct = packed struct {
    a: u8,
    b: u32,
    c: u8,
};

pub fn main() void {
    std.debug.print("PackedStruct size: {}\n", .{@sizeOf(PackedStruct)});
}

6.3 extern 结构体 #

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

const ExternStruct = extern struct {
    a: u8,
    b: u32,
    c: u8,
};

pub fn main() void {
    std.debug.print("ExternStruct size: {}\n", .{@sizeOf(ExternStruct)});
}

七、实战示例 #

7.1 链表 #

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

const Node = struct {
    value: i32,
    next: ?*Node,
    
    fn create(value: i32) Node {
        return .{ .value = value, .next = null };
    }
};

const LinkedList = struct {
    head: ?*Node,
    len: usize,
    
    fn init() LinkedList {
        return .{ .head = null, .len = 0 };
    }
    
    fn prepend(self: *LinkedList, node: *Node) void {
        node.next = self.head;
        self.head = node;
        self.len += 1;
    }
    
    fn print(self: LinkedList) void {
        var current = self.head;
        while (current) |node| {
            std.debug.print("{} -> ", .{node.value});
            current = node.next;
        }
        std.debug.print("null\n", .{});
    }
};

pub fn main() void {
    var list = LinkedList.init();
    
    var n1 = Node.create(1);
    var n2 = Node.create(2);
    var n3 = Node.create(3);
    
    list.prepend(&n1);
    list.prepend(&n2);
    list.prepend(&n3);
    
    list.print();
}

7.2 栈 #

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

fn Stack(comptime T: type, comptime capacity: usize) type {
    return struct {
        items: [capacity]T,
        top: usize,
        
        const Self = @This();
        
        fn init() Self {
            return .{
                .items = undefined,
                .top = 0,
            };
        }
        
        fn push(self: *Self, item: T) !void {
            if (self.top >= capacity) return error.StackFull;
            self.items[self.top] = item;
            self.top += 1;
        }
        
        fn pop(self: *Self) ?T {
            if (self.top == 0) return null;
            self.top -= 1;
            return self.items[self.top];
        }
        
        fn peek(self: Self) ?T {
            if (self.top == 0) return null;
            return self.items[self.top - 1];
        }
    };
}

pub fn main() !void {
    var stack = Stack(i32, 10).init();
    
    try stack.push(1);
    try stack.push(2);
    try stack.push(3);
    
    while (stack.pop()) |value| {
        std.debug.print("Popped: {}\n", .{value});
    }
}

八、总结 #

结构体要点:

特性 说明
定义 const Name = struct { ... }
默认值 field: T = default
方法 fn name(self: Self)
关联函数 fn name() 无 self
packed 紧凑布局
extern C 兼容布局

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

最后更新:2026-03-27