文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
7.6 联合
不同于结构体字段各自拥有独立的内存地址和存储空间,联合(union)各字段共享内存地址和存储空间。简单点说,就是同一块内存,以不同视角(field type)进行读写。
- 尺寸由长度最大的字段类型决定。
- 默认各字段起始地址相同。
- 初始化表达式只能有一个字段。
- 共享内存,对字段操作是不安全的(unsafe)。
use std::mem::size_of_val; union Data { int: i32, byte: u8, } fn main() { let d = Data{ int: 0 }; unsafe { // 尺寸由长度最大的字段决定。 assert_eq!(size_of_val(&d), size_of_val(&d.int)); // 各字段共享内存和起始地址。 let p1: *const i32 = &d.int; let p2: *const u8 = &d.byte; assert_eq!(p1 as usize, p2 as usize); } }
以不同字段视角去读写联合体内存。
union Data { int: i32, bytes: [u8; 4], } fn main() { let mut d = Data{ int: 0x112233 }; unsafe { // 以另一个字段的视角读取内存。 assert_eq!(d.bytes, [0x33, 0x22, 0x11, 0]); // 以另一个字段修改数据。 d.bytes[1] = 0x55; assert_eq!(d.int, 0x115533); } }
匹配操作与结构体类似。
union Data { int: i32, bytes: [u8; 4], } fn main() { let d = Data{ int: 0x112233 }; unsafe { match d { Data { int: 0x1122 } => { println!("int: {:x}", d.int); } Data { bytes } => { println!("bytes: {:#?}", bytes); } } } }
因各字段共享内存,对一个字段进行可变引用,就相当于其他字段也处于可变引用状态。
fn main() { let mut d = Data{ int: 0x112233 }; unsafe { let a = &mut d.int; ---------- first mutable borrow occurs here (via `d.int`) let b = &mut d.bytes; ^^^^^^^^^^^^ second mutable borrow occurs here (via `d.bytes`) *a += 1; ------- first borrow later used here } }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论