Zig的结构体是值类型,支持默认值、方法和泛型:
const std = @import("std");
const Point = struct {
x: f64,
y: f64,
z: f64 = 0.0,
pub fn distance(self: Point) f64 {
return std.math.sqrt(self.x*self.x + self.y*self.y + self.z*self.z);
}
pub fn origin() Point {
return .{ .x=0, .y=0, .z=0 };
}
pub fn translate(self: *Point, dx: f64, dy: f64) void {
self.x += dx;
self.y += dy;
}
};
pub fn main() !void {
var p = Point{ .x=3.0, .y=4.0 };
std.debug.print("距离: {d:.2}\n", .{p.distance()});
var p2 = Point.origin();
p2.translate(1.0, 2.0);
std.debug.print("p2=({d:.1},{d:.1})\n", .{p2.x, p2.y});
}
z: f64 = 0.0origin())const Point{.x,.y,.z} = p;.{1, 2}当类型已知时// 泛型结构体——comptime返回类型
fn Stack(comptime T: type) type {
return struct {
items: []T,
len: usize,
pub fn push(self: *@This(), item: T) !void {
if (self.len >= self.items.len) return error.Overflow;
self.items[self.len] = item;
self.len += 1;
}
pub fn pop(self: *@This()) ?T {
if (self.len == 0) return null;
self.len -= 1;
return self.items[self.len];
}
pub fn peek(self: *const @This()) ?T {
if (self.len == 0) return null;
return self.items[self.len-1];
}
};
}
// 自定义format输出
const Vec3 = struct {
x:f32, y:f32, z:f32,
pub fn add(a:Vec3, b:Vec3) Vec3 {
return .{.x=a.x+b.x, .y=a.y+b.y, .z=a.z+b.z};
}
pub fn dot(a:Vec3, b:Vec3) f32 {
return a.x*b.x + a.y*b.y + a.z*b.z;
}
pub fn length(self:Vec3) f32 {
return std.math.sqrt(self.dot(self));
}
pub fn format(self:Vec3, comptime fmt:[]const u8,
options:std.fmt.FormatOptions, writer:anytype) !void {
_=fmt; _=options;
try writer.print("Vec3({d:.2},{d:.2},{d:.2})", .{self.x,self.y,self.z});
}
};
pub fn main) !void {
var buf: [10]i32 = undefined;
var stack = Stack(i32){ .items=&buf, .len=0 };
try stack.push(42);
try stack.push(99);
std.debug.print("pop: {}\n", .{stack.pop().?});
const a = Vec3{.x=1,.y=2,.z=3};
const b = Vec3{.x=4,.y=5,.z=6};
std.debug.print("a+b={} |a|={d:.2}\n", .{Vec3.add(a,b), a.length()});
}
泛型通过comptime单态化,每个类型实例化一份代码,零虚调开销。@This()在编译期替换为实际类型。方法编译为普通函数,self按值或指针传递。
const Color = enum { red, green, blue };
// 指定标签类型
const Opcode = enum(u8) {
NOP=0x00, LOAD=0x01, STORE=0x02,
ADD=0x03, SUB=0x04, HALT=0xFF,
};
// 带方法的枚举
const HttpStatus = enum(u16) {
ok=200, not_found=404, server_error=500,
pub fn isSuccess(self:HttpStatus) bool {
const code = @intFromEnum(self);
return code >= 200 and code < 300;
}
};
// 非穷举枚举——接收任意底层值
const Token = enum(u8) { Ident, Number, String, _, };
pub fn main() !void {
const c = Color.red;
std.debug.print("HALT=0x{X:0>2}\n", .{@intFromEnum(Opcode.HALT)});
const op = std.meta.intToEnum(Opcode, 0x03) catch unreachable;
std.debug.print("名称: {s}\n", .{@tagName(c)});
inline for (std.meta.fields(Color)) |field| {
std.debug.print("Color.{s}\n", .{field.name});
}
}
| 类型 | 底层值 | 穷举 | 用途 |
|---|---|---|---|
enum | 自动 | 是 | 一般枚举 |
enum(u8) | 指定 | 是 | 协议/指令 |
enum(u8){..., _} | 指定 | 否 | 外部数据 |
// 标签联合体——类型安全变体
const Value = union(enum) {
int_val: i64,
float_val: f64,
string_val: []const u8,
bool_val: bool,
};
pub fn main() !void {
var val = Value{ .int_val=42 };
switch (val) {
.int_val => |v| std.debug.print("整数: {}\n", .{v}),
.float_val => |v| std.debug.print("浮点: {d}\n", .{v}),
.string_val => |v| std.debug.print("字符串: {s}\n", .{v}),
.bool_val => |v| std.debug.print("布尔: {}\n", .{v}),
}
// 指针捕获修改
switch (val) {
.int_val => |*v| v.* += 1,
else => {},
}
}
const Flags = packed struct {
carry: bool, zero: bool, interrupt: bool,
decimal: bool, overflow: bool, _pad: u3=0,
};
const CtrlReg = packed struct {
enable: u1, mode: u2, prescaler: u3, _reserved: u2,
};
pub fn main() !void {
var flags = Flags{.carry=true,.zero=false,.interrupt=true,.decimal=false,.overflow=false};
flags.carry = false;
const bits: u8 = @bitCast(flags);
std.debug.print("标志: 0b{b:0>8}\n", .{bits});
const reg = CtrlReg{.enable=1,.mode=2,.prescaler=5,._reserved=0};
std.debug.print("寄存器: 0x{X:0>2}\n", .{@as(u8, @bitCast(reg))});
}
packed struct无填充,与C布局兼容。位字段编译为掩码+移位,与手动位操作等价。适合寄存器映射和协议头解析。
泛型双向链表push/pop/insert
标签联合体JsonValue支持6种类型
packed struct模拟x86 EFLAGS
枚举+标签联合体词法分析器
packed struct解析20字节头部