开发环境
- Windows 10
- Rust 1.58.1
- VS Code 1.64.2
项目工程
这里继续沿用上次工程rust-demo
枚举和模式匹配
枚举允许您通过枚举类型的可能变体来定义类型。首先,我们将定义并使用一个枚举来展示一个枚举如何编码数据的含义。接下来,我们将探索一个特别有用的枚举,称为Option,它表示一个值可以是某个值,也可以是零。然后,我们将看看match表达式中的模式匹配是如何简化为枚举的不同值运行不同代码的。最后,我们将介绍if let构造如何成为另一种方便、简洁的习惯用法,让您在代码中处理枚举。
枚举是许多语言中的一个特性,但是它们的功能在每种语言中都有所不同。
定义枚举
让我们来看一个我们可能想要用代码表达的情况,看看为什么在这种情况下枚举是有用的并且比结构更合适。假设我们需要处理IP地址。目前,IP地址使用两种主要标准:第四版和第六版。这些是我们的程序将遇到的IP地址的唯一可能性:我们可以枚举所有可能的变体,这就是枚举的名称。
任何IP地址都可以是版本四或版本六地址,但不能同时是两者。IP地址的该属性使得enum数据结构是合适的,因为enum值只能是其变体之一。第四版和第六版地址基本上都是IP地址,所以当代码处理适用于任何类型IP地址的情况时,它们应该被视为相同的类型。
我们可以通过定义IpAddrKind枚举并列出IP地址的可能类型(V4和V6)来用代码表达这个概念。这些是枚举的变体,如下所示:
// 定义枚举
enum IpAddrKind {
V4,
V6,
}
IpAddrKind现在是一个自定义数据类型,我们可以在代码中的其他地方使用它。
枚举值
我们可以创建IpAddrKind的两种变体的实例,如下所示:
// 使用枚举的值
let four = IpAddrKind::V4;
let six = IpAddrKind::V6;
请注意,枚举的变体是在其标识符下命名的,我们使用一个双冒号来分隔两者。这很有用的原因是,现在值IpAddrKind::V4和IpAddrKind::V6属于同一类型:IpAddrKind。
例如,我们可以定义一个接受任何IpAddrKind的函数:
fn route(ip_kind: IpAddrKind) {}
我们可以用任何一个变量来调用这个函数:
// 调用
route(IpAddrKind::V4);
route(IpAddrKind::V6);
使用枚举有更多的优点。多想想我们的IP地址类型,目前我们没有办法存储实际的IP地址数据;我们只知道是哪一种。刚刚学习了前面的结构体,可以定义如下所示的代码解决一些问题。
// 枚举
enum IpAddrKind {
V4,
V6,
}
// 结构体
struct IpAddr {
kind: IpAddrKind,
address: String,
}
// 结构体变量初始化
let home = IpAddr {
kind: IpAddrKind::V4,
address: String::from("127.0.0.1"),
};
let loopback = IpAddr {
kind: IpAddrKind::V6,
address: String::from("::1"),
};
这里,我们定义了一个结构体IpAddr