Unions and Tagged Unions
14.1 Bare Unions
const Value = union {
int: i64,
float: f64,
};
var v = Value{ .int = 42 };
v = Value{ .float = 3.14 }; // switch the active field by reassigning
// reading an inactive field is illegal behavior (checked in safe modes)14.2 Tagged Unions (Sum Types)
With an explicit tag enum: union(MyTagEnum) { ... }.
Common uses: AST nodes, tokens, JSON values, messages, state machines.
const Shape = union(enum) {
circle: f32, // radius
rect: struct { w: f32, h: f32 },
triangle: struct { a: f32, b: f32, c: f32 },
point, // void payload
pub fn area(self: Shape) f32 {
return switch (self) {
.circle => |r| std.math.pi * r * r,
.rect => |d| d.w * d.h,
.triangle => |t| blk: {
const s = (t.a + t.b + t.c) / 2;
break :blk @sqrt(s * (s - t.a) * (s - t.b) * (s - t.c));
},
.point => 0,
};
}
};
var s: Shape = .{ .circle = 2 };
std.debug.print("{d}\n", .{s.area()});
switch (s) {
.circle => |*r| r.* *= 2, // mutate the payload through a pointer capture
else => {},
}
if (s == .circle) {} // compare against the tag
const tag = std.meta.activeTag(s);
_ = tag;14.3 Extern and Packed Unions
extern union gives a C-compatible union. packed union gives a bit-level union (all fields share the same bits).