Union

From Rust Community Wiki
Jump to navigation Jump to search

Union types are like enums that don't store the currently used variant. Accessing a union field is inherently unsafe because of this. Unions were added to Rust for better compatibility with C, but are useful in pure Rust as well.

A union has several fields that share the same memory. Therefore, when instantiating a union, only one of its fields is specified. It is possible to access a different field of a union than the one that was previously set, which re-interprets the bytes similarly to mem::transmute()This links to official Rust documentation.

Like struct fields, union fields are private by default and can have visibility modifiers.

Example[edit | edit source]

union Foo {
    a: u32,
    b: [u8; 4],
}

// Convert 4 bytes to a u32:
unsafe {
    Foo { b: [1, 2, 3, 4] }.a
}

Note that the above is sound: u32 has the same size as [u8; 4]. Furthermore, the union ensures that both values have the same alignment, which isn't the case for mem::transmute().

Fields of different sizes[edit | edit source]

Unions can contain fields of different sizes. In that case, the size of the union equals the size of its biggest field, including padding. One use case is the MaybeUninitThis links to official Rust documentation type:

pub union MaybeUninit<T> {
    uninit: (),
    value: ManuallyDrop<T>,
}

This union allows manually initializing a value, such as an array, without overhead.

Limitations[edit | edit source]

Currently, unions can only contain types that implement CopyThis links to official Rust documentation. Note that MaybeUninit uses the untagged_unions nightly feature to support non-Copy values.