Я нашел это решение в библиотеке C под названием «Математика ручной работы»:
typedef union hmm_vec2 {
struct { float X, Y; };
struct { float U, V; };
struct { float Left, Right; };
struct { float Width, Height; };
float Elements[2];
} hmm_vec2;
В C это решение позволяет обращаться к одной и той же памяти под разными именами. Допустим, у вас есть переменная my_vec2, вы можете сказать my_vec2.x, my_vec2.Height, my_vec2[0]
Преимущество этого в том, что вам не нужно определять разные типы для одной и той же структуры данных, но с разными именами полей.
Не могли бы вы сделать что-то подобное в Zig? Я немного попробовал, но не смог заставить это работать.
Вот что я пробовал, но не работает. Я не понимаю, почему поля не извлекаются с использованием пространства имен.
const vec2 = union {
usingnamespace struct { x: i32, y: i32 };
usingnamespace struct { w: i32, h: i32 };
elems: [2]i32,
};





Кое-что из этого можно воспроизвести с помощью упакованного объединения и упакованной структуры, но Zig не допускает массивов ни в packed union, ни в packed struct.
const log = @import("std").log;
const TestUnion = packed union {
coords: packed struct { x: f32, y: f32 },
size: packed struct { width: f32, height: f32 },
// elements: [2]f32, // error: packed unions cannot contain fields of type '[2]f32'
// note: type has no guaranteed in-memory representation
};
pub fn main() !void {
const test_union = TestUnion{ .coords = .{ .x = 1.2, .y = 3.4 } };
log.info("coords: {}, {}", .{ test_union.coords.x, test_union.coords.y });
log.info("size: {}, {}", .{ test_union.size.width, test_union.size.height });
}
$ zig build run
info: coords: 1.2e0, 3.4e0
info: size: 1.2e0, 3.4e0
my_vec2[0]неправильно, этоmy_vec2.Elements[0]. Иmy_vec2.xдолжно бытьmy_vec2.X(C учитывает регистр).