结构体基础 #
一、结构体定义 #
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