# Keyword union

source ·
Expand description

The Rust equivalent of a C-style union.

A `union` looks like a `struct` in terms of declaration, but all of its fields exist in the same memory, superimposed over one another. For instance, if we wanted some bits in memory that we sometimes interpret as a `u32` and sometimes as an `f32`, we could write:

    union IntOrFloat {
        i: u32,
        f: f32,
    }

    let mut u = IntOrFloat { f: 1.0 };
    // Reading the fields of a union is always unsafe
    assert_eq!(unsafe { u.i }, 1065353216);
    // Updating through any of the field will modify all of them
    u.i = 1073741824;
    assert_eq!(unsafe { u.f }, 2.0);

Run

## Matching on unions

It is possible to use pattern matching on `union`s. A single field name must be used and it must match the name of one of the `union`’s field. Like reading from a `union`, pattern matching on a `union` requires `unsafe`.

    union IntOrFloat {
        i: u32,
        f: f32,
    }

    let u = IntOrFloat { f: 1.0 };

    unsafe {
        match u {
            IntOrFloat { i: 10 } => println!("Found exactly ten!"),
            // Matching the field `f` provides an `f32`.
            IntOrFloat { f } => println!("Found f = {f} !"),
        }
    }

Run

## References to union fields

All fields in a `union` are all at the same place in memory which means borrowing one borrows the entire `union`, for the same lifetime:

ⓘ

    union IntOrFloat {
        i: u32,
        f: f32,
    }

    let mut u = IntOrFloat { f: 1.0 };

    let f = unsafe { &u.f };
    // This will not compile because the field has already been borrowed, even
    // if only immutably
    let i = unsafe { &mut u.i };

    *i = 10;
    println!("f = {f} and i = {i}");

Run

See the Reference for more information on `union`s.