【RUST学习日记】第24课 枚举(Enum)

简介: 【RUST学习日记】第24课 枚举(Enum)

0x00 回顾


上篇文章咱们介绍了结构体,结构体类型是一种自定义的数据类型,当然也可以把 多个类型组合在一起成为新的类型。本篇文章介绍另一种自定义数据类型——枚举(enum)。一起来看看它和结构体又有什么区别吧


0x01 定义


枚举类型是一种自定义的数据类型,使用 **enum **关键字 + 自定义的命名 + 枚举值来定义。我们通过使用 枚举名 :: 枚举值 来访问枚举的值。使用场景:当一个参数可能存在多个取值范围时,我们定义成枚举类型来控制变量的取值范围,从而防止输入非法值。示例代码如下:

// 枚举示例代码// 声明一个星期的枚举类型,只有7天,周一到周日。
enum Week {
    Mon,
    Tue,
    Wed,
    Thu,
    Fri,
    Sat,
    Sun
}


0x02 C 式枚举


上面的示例代码,就是Rust中最简单的枚举类型了,同 C 语言 一模一样。在内存中,C 式枚举的值存储为整数,默认从0开始,后面的值依次 +1。如果想更改某个枚举的值,需要告诉它用什么整数。示例代码如下:

// 为了可以格式化打印枚举值,需要加入下面这行代码,具体有关 trait 的知识将在后面介绍。
#[derive(Debug)]enum Week {
    Mon,
    Tue,
    Wed,
    Thu = 300,
    Fri,
    Sat,
    Sun}fn main() {
    // 打印枚举类型
    println!("{:?}", Week::Wed);
    // 打印枚举的值
    println!("{}", Week::Wed as i32);
    println!("{}", Week::Mon as i32);
    // 由于Thu 赋值维 300, 则后面的值依次+1
    println!("{}", Week::Fri as i32);
}
// 输出结果:
// Wed
// 2
// 0
// 301


0x03 包含数据的枚举


在 Rust 中,枚举的值存在 3 种变体,分别对应前两篇文章介绍的 3 种结构体。没有数据的变体对应类基元结构体,元组变体的写法和作用同元组结构体一样,结构体变体则存在花括号和命名字段。在一个枚举里可以同时存在3 种变体。


#[derive(Debug)]
enum Color {
    // 定义色值,参数分别表示16进制颜色代码,R,G,B
    White(String, u8, u8, u8),
    Red,
    Black { code: String, r: u8, g: u8, b: u8 },
}
fn main() {
    let white = Color::White(String::from("#FFFFFF"), 255, 255, 255);
    let red = Color::Red;
    let black = Color::Black { 
                    code: String::from("#000000"), 
                    r: 0, 
                    g: 0, 
                    b: 0
                 };
    println!("{:?}", white);
    println!("{:?}", red);
    println!("{:?}", black);   
    // 输出结果:
    // White("#FFFFFF", 255, 255, 255)
    // Red
    // Black { code: "#000000", r: 0, g: 0, b: 0 }
}


0x04 枚举的内存布局


我们以 Week 为例,来看下枚举在内存中的布局吧。废话不多说,先上图,后解释。


0a2653c851af460fa595bd959398a8f1.png


不知道大家能不能看懂呢。首先如果一个枚举类型存在多个枚举值,那么它会为每个枚举值分配一个标签,从0开始计数,占1字节。我们每个枚举值,还有3个u8类型的值,每个类型占1字节。由于对齐原因,留空4字节,对齐8字节(有关Rust内存对齐的问题,我找时间单独一篇文章介绍)。最后String占24字节,关于String的内存模型,我已经在前面讲过了。Week 总共占 32 字节

最后,我们通过编译器验证下内存数据。如下图:


2d65d23f6d4748949b924e4057485923.png


另外,如果一个枚举类型仅存在一个枚举值,那么他不会存在占一个字节的标签。大家可通过编译器自行验证。我在这里就不做赘述了。

注:上面的内存模型是以 Rust 1.62.1 版本为基础的。Rust 后续依然可能会对枚举的内存作出优化。


0x05 小结


枚举类型到这里就介绍完了,其实枚举在任何项目中都是很常见的。本篇文章主要介绍了枚举的定义和内存布局,使用枚举的是为了必须保证安全的访问数据,在某些场景下大概率会同模式匹配一起使用。


介绍了枚举类型之后,Rust 常用的数据类型已经介绍完了。之后的文章将进入 Rust 中级阶段,了解 Rust 的泛型,Trait,所有权指针等等。接下来的文章将是真正揭开 Rust 神秘面纱的时刻。

相关文章
|
18天前
|
Rust 安全 网络协议
Rust 笔记:Rust 语言中的枚举 与 模式匹配
Rust 笔记:Rust 语言中的枚举 与 模式匹配
49 0
|
18天前
|
Rust 安全 算法
【深入探索Rust:结构体、枚举与模式匹配】A Deep Dive into Rust: Structs, Enums, and Pattern Matching
【深入探索Rust:结构体、枚举与模式匹配】A Deep Dive into Rust: Structs, Enums, and Pattern Matching
53 0
【深入探索Rust:结构体、枚举与模式匹配】A Deep Dive into Rust: Structs, Enums, and Pattern Matching
|
18天前
|
JSON Rust IDE
全网最全的Rust学习资源
学习Rust过程中整理了一些学习资料分享一下。
123 1
|
18天前
|
C++ Rust NoSQL
Rust 数据类型 之 类C枚举 c-like enum
Rust 数据类型 之 类C枚举 c-like enum
35 0
Rust 数据类型 之 类C枚举 c-like enum
|
18天前
|
Rust
Rust编程语言:探索性学习与实践指南
Rust编程语言:探索性学习与实践指南
38 0
|
18天前
|
Rust 编译器
【一起学Rust】Rust学习前准备——注释和格式化输出
【一起学Rust】Rust学习前准备——注释和格式化输出
41 0
|
18天前
|
Rust JavaScript 前端开发
Rust 枚举和模式匹配
Rust 枚举和模式匹配
|
6月前
|
Rust
Rust编程语言:探索性学习与实践指南
Rust编程语言:探索性学习与实践指南
34 0
|
6月前
|
Rust 前端开发 安全
致所有渴望学习Rust的人的信
致所有渴望学习Rust的人的信
|
Rust 网络协议 编译器
Rust学习笔记之枚举和匹配模式
1. Rust中枚举类型 推荐阅读指数 ⭐️⭐️⭐️⭐️⭐️ 2. match 控制流运算符 推荐阅读指数 ⭐️⭐️⭐️⭐️ 3. if let 简单控制流 推荐阅读指数 ⭐️⭐️⭐️⭐️
Rust学习笔记之枚举和匹配模式