Expand description
union 在声明方面看起来像 struct,但是它的所有字段都存在于同一内存中,彼此叠加在一起。
例如,如果我们希望内存中的某些位有时被解释为 u32,有时又被解释为 f32,则可以这样写:
union IntOrFloat {
i: u32,
f: f32,
}
let mut u = IntOrFloat { f: 1.0 };
// 读取 union 的字段总是不安全的
assert_eq!(unsafe { u.i }, 1065353216);
// 通过任何字段进行更新都会修改所有字段
u.i = 1073741824;
assert_eq!(unsafe { u.f }, 2.0);Rununion 上的匹配
可以在 union 上使用模式匹配。
必须使用单个字段名称,并且该名称必须与 union 字段之一的名称匹配。
就像从 union 读取一样,在 union 上进行模式匹配时也需要 unsafe。
union IntOrFloat {
i: u32,
f: f32,
}
let u = IntOrFloat { f: 1.0 };
unsafe {
match u {
IntOrFloat { i: 10 } => println!("Found exactly ten!"),
// 匹配字段 `f` 将提供 `f32`。
IntOrFloat { f } => println!("Found f = {f} !"),
}
}Rununion 字段的引用
union 中的所有字段都在内存中的同一位置,这意味着对于同一生命周期,整个 union 都用一个借用。
ⓘ
union IntOrFloat {
i: u32,
f: f32,
}
let mut u = IntOrFloat { f: 1.0 };
let f = unsafe { &u.f };
// 这将不会编译,因为该字段已被借用,即使只是一成不变
let i = unsafe { &mut u.i };
*i = 10;
println!("f = {f} and i = {i}");Run有关 union 的更多信息,请参见 Reference。