Note: None of this capability is currently implemented.
Like enums, unions allow a value's type structure to vary. Unions permit greater data structure flexibility than enums, because they make the nature of the tag more explicit.
The safe way to use a union is within a struct, where the union points to the explicit tag field in the struct:
struct Event evtype u32 time Time union : evtype MouseButton button u8 x i32 y i32 Keyboard keysym KeySym Quit
The Event type encodes user-initiated events, such as clicking a mouse button, pressing a key on the keyboard, or quitting the program. These are variant types of events, that all share some fields in common, such as time's timestamp info. Each event type also defines its own specific fields. Notice that union points to the common evtype field, making it the type's tag field used to determine which variant type a value holds.
The union's declaration looks largely identical to that of an enum. An important difference is that a union needs to specify which of the enclosing struct's fields is to be used as the discriminating tag.
Unions may be used inside a union. These unions rely on the same tag, further differentiating variations. This approach supports a classification hierarchy, allowing shared fields for any grouping of variants. Only the final variants may be instantiated with values.
A union-based struct value is built using a variation of the struct constructor:
mut event = Event::MouseButton[now, button: 0, x: 140, y: 170] event = Event::Keyboard[now, 'a'] event = Event::Quit[now]
How this differs from a normal struct constructor should be pretty obvious: instead of giving the tag's value inside the constructor, we qualify the type's name with the type of the variant.
A struct value with an embedded union may be passed around, by copy, just like any other value. As with enums, all variant values of a union-based struct type are the same size.
Any field in common across all variants may be accessed in the same way as any normal field:
imm when = event.time
However, much like enum, to safely gain access to any of the union-declared variant fields, we must use pattern matching:
match event ~~ mbutton = MouseButton: mbutton.x ~~ key = Keyboard: i32[key.keysym] ~~ Quit: 0
Just like with vanilla structs, two union-based struct values may be only compared if the struct implements the comparison methods.