基本用法
比如使用枚举定义颜色[1]:
enum Color {
Red,
Orange,
Yellow
}
let c1 = Color::Red;
let c2 = Color::Orange;
match c1 {
Color::Red => println!("Red"),
Color::Orange => println!("Orange"),
Color::Yellow => println!("Yellow")
}
任何类型的数据都可以放入枚举成员中:例如字符串、数值、结构体甚至另一个枚举[2]。
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let m1 = Message::Quit;
let m2 = Message::Move{x:1,y:1};
let m3 = Message::ChangeColor(255,255,0);
}
给枚举实现方法
枚举也可以有方法,像结构体一样,使用 impl
关键字,基于 new
方法创建的 Message
实例。[1]
impl Message {
...
fn handle_quit(&self) -> Message {
// 处理 Quit 逻辑
}
}
match quit_message {
Message::Quit => Message::new().handle_quit(),
...
}
带数据的枚举在Rust中非常有用,因为允许在单个类型中封装多种不同的行为或状态,同时保持类型安全。经常用于表示命令、事件、消息或其他需要关联数据的等场景。
泛型枚举
泛型枚举可以接受一个或多个类型参数。如 Rust 标准库中的两个例子
enum Option<T> {
Some(T),
None,
}
enum Result<T, E> {
Ok(T),
Err(E),
}
Option 枚举用于处理空值[2]
在其它编程语言中,往往都有一个 null
关键字,该关键字用于表明一个变量当前的值为空(不是零值,例如整型的零值是 0
),也就是不存在值。当你对这些 null
进行操作时,例如调用一个方法,就会直接抛出 null
异常,导致程序的崩溃,因此我们在编程时需要格外的小心去处理这些 null
空值。
尽管如此,空值的表达依然非常有意义,因为空值表示当前时刻变量的值是缺失的。有鉴于此, Rust
吸取了众多教训,决定抛弃 null
,而改为使用 Option
枚举变量来表述这种结果。
Option
枚举包含两个成员,一个成员表示含有值: Some(T)
, 另一个表示没有值: None
,定义如下:
enum Option<T> {
Some(T),
None,
}
其中 T
是泛型参数, Some(T)
表示该枚举成员的数据类型是 T
,换句话说, Some
可以包含任何类型的数据。
Option<T>
枚举是如此有用以至于它被包含在了 prelude
( prelude
属于 Rust 标准库,Rust 会将最常用的类型、函数等提前引入其中,省得我们再手动引入)之中,你不需要将其显式引入作用域。另外,它的成员 Some 和 None
也是如此,无需使用 Option::
前缀就可直接使用 Some
和 None
。总之,不能因为 Some(T)
和 None
中没有 Option::
的身影,就否认它们是 Option
下的卧龙凤雏。
Result 返回值
Result<T, E>
是一个用来返回值和成功、错误值的类型:携带变量的枚举类型。 Ok(T)
表示成功,并且包含返回值, T
表示正确的返回值变量的类型(T为泛型); Err(E)
表示失败,并且包含了返回值, E
表示错误的返回值的类型(泛型)。
enum Result<T, E> {
Ok(T),
Err(E),
}
枚举的底层原理
在内存中,带有数据的枚举会以一个小型整数标签加上足以容纳最大变体中所有字段的内存块的格式进行存储。标签字段供 Rust 内部使用。它会区分由哪个构造器创建了值,进而决定这个值应该有哪些字段。[1]
enum RoughTime {
InThePast(TimeUnit, u32),
JustNow,
InTheFuture(TimeUnit, u32),
}
原理就是取所有枚举占用的最大字节,作为枚举的大小:
-
需要字节区分枚举是哪个
-
需要字节储存枚举的实际数据
-
字节对齐的需要
参考
- ^abcRust枚举深度解析:构建灵活的数据结构 https://cloud.tencent.com/developer/article/2415747
- ^abRust语言圣经(Rust Course) - 枚举 https://course.rs/basic/compound-type/enum.html