Rust学习笔记_15——Union

Rust学习笔记_12------闭包
Rust学习笔记_13------枚举
Rust学习笔记_14------结构体


Union

文章目录

    • Union
      • [1. 基本用法](#1. 基本用法)
      • [2. 注意事项](#2. 注意事项)
      • [3. 示例](#3. 示例)

在Rust编程语言中,union 是一种特殊的数据结构,允许你在同一个内存位置存储不同类型的值。这与枚举(enum)有些相似,但有一个关键的不同点:在 union 中,所有的字段共享同一块内存,这意味着在任何给定时间,union 只能安全地包含一个有效的值。

1. 基本用法

rust 复制代码
#[repr(C)]
union MyUnion {
    i: i32,
    f: f32,
    s: [u8; 4],
}

// MyUnion 可以在同一个内存位置存储一个 i32、一个 f32 或一个由4个 u8 组成的数组。
// #[repr(C)] 属性确保 union 的布局与C语言中的 union 布局一致,这对于与C语言代码进行互操作非常有用

2. 注意事项

  1. 内存布局union 的内存布局是固定的,并且与C语言的 union 兼容。因此,它们常用于与C代码进行互操作。
  2. 安全性 :直接访问 union 中的字段是不安全的,因为你无法确定当前哪个字段是有效的。因此,通常结合枚举来跟踪状态,并在安全的情况下访问 union 中的数据。
  3. 生命周期union 本身不包含生命周期信息,因此在使用包含引用的 union 时需要特别小心,以避免悬挂指针或未定义行为。

3. 示例

rust 复制代码
// 这里定义了一个 union,名为 MyUnion,它可以在同一个内存位置存储一个 i32、一个 f32 或一个由4个 u8 组成的数组。
// #[repr(C)] 属性确保 union 的布局与C语言中的 union 布局一致。
#[repr(C)]
union MyUnion {
    i: i32,
    f: f32,
    s: [u8; 4],
}

// 这个枚举用于跟踪 union 中当前存储的数据类型。每个变体都包含与 union 中相应字段相同类型的值。
#[derive(Debug)]
enum MyUnionState {
    Int(i32),
    Float(f32),
    Bytes([u8; 4]),
}

// 结构体 MyStruct 包含两个字段:data(MyUnion 类型)和 state(MyUnionState 类型)。
// data 字段用于存储实际的数据
// state 字段用于跟踪当前存储的数据类型。
struct MyStruct {
    data: MyUnion,
    state: MyUnionState,
}

// 为 MyStruct 实现了两个构造函数:new_int 和 new_float。
// 这些函数分别用于创建包含 i32 和 f32 值的 MyStruct 实例。
impl MyStruct {
    fn new_int(value: i32) -> Self {
        MyStruct {
            data: MyUnion { i: value },
            state: MyUnionState::Int(value),
        }
    }

    fn new_float(value: f32) -> Self {
        MyStruct {
            data: MyUnion { f: value },
            state: MyUnionState::Float(value),
        }
    }

    fn value_int(&self) -> Option<i32> {
        if let MyUnionState::Int(value) = &self.state {
            Some(unsafe { self.data.i })
        } else {
            None
        }
    }

    fn value_float(&self) -> Option<f32> {
        if let MyUnionState::Float(value) = &self.state {
            Some(unsafe { self.data.f })
        } else {
            None
        }
    }
}

fn main() {
    let int_val = MyStruct::new_int(42);
    let float_val = MyStruct::new_float(3.14);

    println!("Int value: {:?}", int_val.value_int());
    println!("Float value: {:?}", float_val.value_float());
}
相关推荐
烧冻鸡翅QAQ2 分钟前
考研408笔记——数据结构
数据结构·笔记·考研
lkbhua莱克瓦241 小时前
集合进阶6——TreeMap底层原理
java·开发语言·笔记·学习方法·hashmap
T***u3331 小时前
后端缓存技术学习,Redis实战案例
redis·学习·缓存
Gorgous—l1 小时前
数据结构算法学习:LeetCode热题100-图论篇(岛屿数量、腐烂的橘子、课程表、实现 Trie (前缀树))
数据结构·学习·算法
im_AMBER1 小时前
算法笔记 13 BFS | 图
笔记·学习·算法·广度优先
烤麻辣烫2 小时前
黑马程序员苍穹外卖(新手) DAY3
java·开发语言·spring boot·学习·intellij-idea
驯狼小羊羔2 小时前
学习随笔-hooks和mixins
前端·javascript·vue.js·学习·hooks·mixins
组合缺一2 小时前
Solon AI 开发学习 - 1导引
java·人工智能·学习·ai·openai·solon
brave and determined3 小时前
可编程逻辑器件学习(day24):异构计算:突破算力瓶颈的未来之路
人工智能·嵌入式硬件·深度学习·学习·算法·fpga·asic
01100001乄夵3 小时前
FPGA零基础入门:TestBench编写完全指南
经验分享·笔记·学习方法·fpga学习之路·fpga 0基础入门