【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 神秘面纱的时刻。

相关文章
|
1月前
|
存储 Rust 网络协议
【Rust学习】10_定义枚举
在这一章我们学习 枚举(enumerations),也被称作 enums。枚举允许你通过列举可能的 成员(variants) 来定义一个类型。首先,我们会定义并使用一个枚举来展示它是如何连同数据一起编码信息的。接下来,我们会探索一个特别有用的枚举,叫做 Option,它代表一个值要么是某个值要么什么都不是。然后会讲到在 match 表达式中用模式匹配,针对不同的枚举值编写相应要执行的代码。最后,我们将学习 if let 结构,另一个简洁方便处理代码中枚举的结构。
39 7
|
4月前
|
Rust 安全 C++
30天拿下Rust之枚举
Rust中的枚举是一种用户定义的类型,它允许你为一组相关的值赋予友好的名称。在Rust中,枚举是强大的工具,它们不仅仅用于表示几个固定的值,还可以包含函数和方法,使得枚举成员可以有自己的行为。通过与模式匹配和其他Rust特性结合使用,枚举在构建健壮、无崩溃的应用程序中发挥了重要作用,并可大幅提高代码的可读性、可维护性和类型安全性。
59 10
|
2月前
|
Rust 算法 安全
学习Rust
【10月更文挑战第13天】学习Rust
60 8
|
2月前
|
Rust 安全 算法
Rust的学习
【10月更文挑战第12天】Rust的学习
30 2
|
2月前
|
Rust 算法 安全
如何学习Rust编程?
【10月更文挑战第12天】如何学习Rust编程?
56 1
|
2月前
|
Rust API
【Rust学习】09_方法语法
结构体让你可以创建出在你的领域中有意义的自定义类型。通过结构体,我们可以将相关联的数据片段联系起来并命名它们,这样可以使得代码更加清晰。在 impl 块中,你可以定义与你的类型相关联的函数,而方法是一种相关联的函数,允许您指定结构体的实例具有的行为。 但是结构体并不是创建自定义类型的唯一方式:让我们转向 Rust 的 enum 功能,将另一个工具添加到你的工具箱中。
22 0
|
3月前
|
Rust 索引
【Rust学习】08_使用结构体代码示例
为了了解我们何时可能想要使用结构体,让我们编写一个计算长方形面积的程序。我们将从使用单个变量开始,然后重构程序,直到我们改用结构体。
100 2
|
3月前
|
存储 Rust 编译器
【Rust学习】07_结构体说明
**struct**或 ***structure***是一种自定义数据类型,允许您命名和包装多个相关的值,从而形成一个有意义的组合。如果您熟悉面向对象的语言,那么**struct**就像对象中的数据属性。在本章中,我们将比较和对比元组与结构体,在您已经知道的基础上,来演示结构体是对数据进行分组的更好方法。
33 1
|
3月前
|
Rust Linux Go
Rust/Go语言学习
Rust/Go语言学习
|
Rust 安全 Java
Rust学习笔记
Rust学习笔记
233 0
Rust学习笔记