Zig 0.16 เทียบ packed union ตาม backing integer: สะดวกแต่ต้องอ่าน representation
Zig 0.16 อนุญาตให้เทียบ packed union โดยตรงแล้วครับ แต่คำว่าเท่ากันในที่นี้ดู backing integer ไม่ได้ดูว่าค่าเข้าผ่าน field ชื่อเดียวกันหรือไม่ ชิ้นส่วนสองแบบจึงอาจมี representation เดียวกันและเท่ากันได้
const std = @import("std");
const Bits = packed union(u2) {
signed: i2,
unsigned: u2,
};
test "packed union equality follows backing bits" {
const left: Bits = .{ .signed = -1 };
const right: Bits = .{ .unsigned = 3 };
try std.testing.expect(left == right);
}
ค่า -1 ใน i2 และ 3 ใน u2 มีบิต 11 เหมือนกัน จึงเท่ากันตามกติกาใหม่ เหมาะกับ register, wire format หรือ bitfield ที่ identity อยู่ในบิตจริง ๆ และลดการห่อ union ด้วย packed struct เพียงเพื่อเทียบ
อย่าสับสน representation กับความหมาย
ถ้า field แทนสถานะธุรกิจคนละชนิด เช่น “เปอร์เซ็นต์” กับ “รหัสข้อผิดพลาด” การเทียบด้วยบิตอาจซ่อน bug แม้ compiler ยอมรับ กรณีนั้น tagged union หรือ enum ที่บังคับดู tag ก่อนเหมาะกว่า และต้องระวัง serialization/cross-version contract เพราะการเปลี่ยน backing type หรือ layout ทำให้ความหมายของ equality เปลี่ยนได้
release notes ยังระบุว่า packed struct/union ใช้เป็น switch prong ได้ในรุ่นนี้ด้วย แต่กติกาเดียวกันคือเปรียบเทียบ backing integer จึงควรมี test ของค่าขอบ เช่นค่าติดลบและค่าสูงสุดทุก field
Recap
- equality ของ packed union ใน 0.16 ดู backing integer
- field คนละชื่ออาจเท่ากันเมื่อบิตเหมือนกัน
- ใช้ tagged union เมื่อ tag เป็นส่วนหนึ่งของความหมาย
- ใส่ regression test ให้ layout ที่ออกสู่ wire/storage