Unions are a data type that can only hold one of its non-static fields at a time. Unions can be created to create invariant data types that can be multiple data types that can be determined dynamically at runtime. Unions have the same exactly functionality like in the C programming language.

Declaring a Union

Here is how you declare a union:

T :: union { 
  a: s64 = 0; 
  b: float64 = 5.0; 
  c: Type; 

t: T;
t.a = 100;
print("t.a = %\n", t.a); // prints out 100
t.b = 3.0;
print("t.b = %\n", t.b); // prints out 3.0
print("t.a = %\n", t.a); // prints out gibberish, since b has been assigned
t.c = s64;
print("t.c = %\n", t.c); // prints out s64
print("t.a = %\n", t.a); // prints out gibberish, since b has been assigned

Accessing a union member field is the same as accessing a struct member field.

You can obtain the same union functionality using #place directives.

T :: struct {
  a: s64; 
  #place a;
  b: float64;
  #place a;
  c: Type; 

In unions or #place directive, when you initialize multiple values to some piece of memory, they get overwritten in that order.

Anonymous Unions

Unions can be declared anonymously, without an identifier to identify what union it is. This feature is useful in the case of creating complex data structures mixing anonymous unions and structs together.

// This is an anonymous union.
variable := union {
  x: int;
  y: int;
  z: int;

// complex Vector3 example using anonymous structs and unions
Vector3 :: struct {
  union {
    struct { x, y, z: float; }
    struct { r, g, b: float; }
    struct { s, t   : float; }