[][src]Function tao_of_rust::ch13::unsafe_intro::union_demo

pub fn union_demo()

Union联合体

也叫共用体、Untagged Union

Basic usage: 使用Union和Struct来模拟Enum - V1

Error: 当前Union不支持Non-Copy类型

// #![feature(untagged_unions)]
#[repr(C)]
union U {
    i: i32,
    f: f32,
}
#[repr(C)]
struct Value{
    tag: u8,
    value: U,
}
#[repr(C)]
union MyZero {
   i: Value,
   f: Value,
}
enum MyEnumZero {
    I(i32),
    F(f32),
}
fn main(){
   let int_0 = MyZero{i: Value{tag: b'0', value: U { i: 0 } } };
   let float_0 = MyZero{i: Value{tag: b'1', value: U { f: 0.0 } } };
}Run

Basic usage: 使用Union和Struct来模拟Enum - V2

#[repr(u32)]
enum Tag { I, F }
#[repr(C)]
union U {
    i: i32,
    f: f32,
}
#[repr(C)]
struct Value {
   tag: Tag,
   u: U,
}
fn is_zero(v: Value) -> bool {
   unsafe {
       match v {
           Value { tag: Tag::I, u: U { i: 0 } } => true,
           Value { tag: Tag::F, u: U { f: 0.0 } } => true,
           _ => false,
       }
   }
}
fn main() {
   let int_0 = Value{tag: Tag::I, u: U{i: 0}};
   let float_0 = Value{tag: Tag::F, u: U{f: 0.0}};
   assert_eq!(true, is_zero(int_0));
   assert_eq!(true, is_zero(float_0));
   assert_eq!(4, std::mem::size_of::<U>());
}Run

Basic usage: 访问Union中未初始化的字段

虽然未报错,但该用法不安全

#[repr(C)]
union U {
    i: i32,
    f: f32,
}
fn main() {
    let u = U{i: 1};
    let i =unsafe{ 
       u.f
   };
   // 0.000000000000000000000000000000000000000000001
   println!("{}", i);
   // 对于一个联合体来说,不能同时使用两个字段
   // 当然也不能同时出借两个字段的可变借用
   // unsafe{ 
   //     let i = &mut u.i;
   //     let f = &mut u.f;
   // };
}Run