union for an unsafe form of enum

Minimum Rust version: 1.19

Rust now supports unions:

  1. #![allow(unused_variables)]
  2. fn main() {
  3. union MyUnion {
  4. f1: u32,
  5. f2: f32,
  6. }
  7. }

Unions are kind of like enums, but they are “untagged”. Enums have a “tag”that stores which variant is the correct one at runtime; unions don't havethis tag.

Since we can interpret the data held in the union using the wrong variant andRust can’t check this for us, that means reading a union’s field is unsafe:

  1. #![allow(unused_variables)]
  2. fn main() {
  3. union MyUnion {
  4. f1: u32,
  5. f2: f32,
  6. }
  7. let mut u = MyUnion { f1: 1 };
  8. u.f1 = 5;
  9. let value = unsafe { u.f1 };
  10. }

Pattern matching works too:

  1. #![allow(unused_variables)]
  2. fn main() {
  3. union MyUnion {
  4. f1: u32,
  5. f2: f32,
  6. }
  7. fn f(u: MyUnion) {
  8. unsafe {
  9. match u {
  10. MyUnion { f1: 10 } => { println!("ten"); }
  11. MyUnion { f2 } => { println!("{}", f2); }
  12. }
  13. }
  14. }
  15. }

When are unions useful? One major use-case is interoperability with C. C APIscan (and depending on the area, often do) expose unions, and so this makeswriting API wrappers for those libraries significantly easier. Additionally,unions also simplify Rust implementations of space-efficient orcache-efficient structures relying on value representation, such asmachine-word-sized unions using the least-significant bits of alignedpointers to distinguish cases.

There’s still more improvements to come. For now, unions can only includeCopy types and may not implement Drop. We expect to lift theserestrictions in the future.