Unions
Las unions de Zig te permiten definir tipos que almacenan un valor de muchos campos con tipos posibles; solo un campo puede estar activo a la vez.
Los tipos de unión sin formato no tienen un diseño de memoria garantizado. Debido a esto, las uniones sin formato no se pueden utilizar para reinterpretar la memoria. Acceder a un campo en una unión que no está activo es un comportamiento ilegal detectable.
const Result = union {
int: i64,
float: f64,
bool: bool,
};
test "simple union" {
var result = Result{ .int = 1234 };
result.float = 12.34;
}
test "simple union"... acceso a un campo inactivo de la unión
. ests.zig:342:12: 0x7ff62c89244a en la prueba "simple union" (test.obj)
result.float = 12.34;
Las uniones etiquetadas son uniones que utilizan una enumeración para detectar qué campo está activo. Aquí volvemos a utilizar la captura de carga útil para cambiar según el tipo de etiqueta de una unión, capturando al mismo tiempo el valor que contiene. Aquí utilizamos una captura de puntero; los valores capturados son inmutables, pero con la sintaxis |*value|, podemos capturar un puntero a los valores en lugar de los valores en sí. Esto nos permite utilizar la desreferenciación para mutar el valor original.
const Tag = enum { a, b, c };
const Tagged = union(Tag) { a: u8, b: f32, c: bool };
test "switch en una unión etiquetada" {
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);
}
El tipo de etiqueta de una unión etiquetada también se puede inferir. Esto es equivalente al tipo Tagged anterior.
const Tagged = union(enum) { a: u8, b: f32, c: bool };
Los tipos de miembros void pueden tener su tipo omitido en la sintaxis. Aquí, none es de tipo void.
const Tagged2 = union(enum) { a: u8, b: f32, c: bool, none };