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。