This commit is contained in:
2026-01-19 05:43:29 +09:00
parent 40f41a4fd0
commit 0f6fddd794
36 changed files with 1724 additions and 0 deletions

49
guide/language/unions.zig Normal file
View File

@@ -0,0 +1,49 @@
const expect = @import("std").testing.expect;
// Zig's unions allow you to define types that store one value of many possible typed fields;
// only one field may be active at one time.
// Bare union types do not have a guaranteed memory layout.
// Because of this, bare unions cannot be used to reinterpret memory.
// Accessing a field in a union that is not active is detectable illegal behaviour.
const Result = union {
int: i64,
float: f64,
bool: bool,
};
test "simple union" {
var result = Result{ .int = 1234 };
result.float = 12.34;
// test "simple union"...access of inactive union field
// .\tests.zig:342:12: 0x7ff62c89244a in test "simple union" (test.obj)
// result.float = 12.34;
// ^
}
// Tagged unions are unions that use an enum to detect which field is active.
// Here we make use of payload capturing again,
// to switch on the tag type of a union while also capturing the value it contains.
// Here we use a pointer capture; captured values are immutable,
// but with the `|*value|` syntax, we can capture a pointer to the values instead of the values themselves.
// This allows us to use dereferencing to mutate the original value.
const Tag = enum { a, b, c };
const Tagged = union(Tag) { a: u8, b: f32, c: bool };
test "switch on tagged union" {
var value = Tagged{ .b = 1.5 };
switch (value) {
.a => |*byte| byte.* += 1,
.b => |*float| float.* *= 2,
.c => |*b| b.* = !b.*,
}
try expect(value.b == 3);
}
// The tag type of a tagged union can also be inferred. This is equivalent to the Tagged type above.
// const Tagged = union(enum) { a: u8, b: f32, c: bool };
// `void` member types can have their type omitted from the syntax. Here, `none` is of type `void`.
const Tagged2 = union(enum) { a: u8, b: f32, c: bool, none };