Rust 枚举
2020-04-04 本文已影响0人
kaiv2
枚举
枚举,也被称作enums。枚举允许你通过列举可能的值来定义一个类型。
定义枚举
enum IpAddrKind {
V4,
V6,
}
枚举值
let four = IpaddrKind::V4;
let six = IpaddrKind::V6;
可以使用任一成员来调用这个函数:
fn route(ip_type: IpAddrKind) -> {}
route(IpAddrKind:V4);
route(IpAddrKind:V6);
使用枚举值还有更多的优势。目前没有一个储存实际 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
:IpaddrKind
类型的 kind
和String
类型的address
字段。
我们可以使用更简洁的方式来表达相同的概念,仅仅使用枚举并将数据直接放进每一个枚举成员而不是将枚举作为结构体的一部分。
enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));
注意虽然标准库中包含一个IpAddr
的定义,仍然可以创建和使用我们自己的定义而不会有冲突,因为我们并没有将标准库中的定义引入作用域。
枚举成员可嵌入多种多样的类型。机构体和枚举还有另一个相识点:可以使用 impl
来为枚举定义方法。
enum Message {
Quit,
Move{ x: i32, y: i32},
Write(String),
ChangeColor(i32, i32, i32),
}
impl Message {
fn call(&self) {
}
}
let m = Message::Write(String::from("hello"));
m.call();
这个枚举有四个含有不同类型的成员:
-
Quit
没有关联任何数据 -
Move
包含一个匿名结构体 -
Write
包含单独一个String
-
ChangeColor
包含三个i32
Option
枚举和其相对于空值的优势
空值的问题在于当你尝试像一个非空值那样使用一个空值,会出现某种形式的错误。因为空和非空的属性无处不在,非常容易出现这类错误。
然而,空值表达式的概念任然是有意义的:空值是一个因为某种原因目前无效或缺失的值。
问题不在于概念而在于具体实现。Rust 并没有空值,不过它确实拥有一个可以编码存在或不存在概念的枚举。这个枚举是Option
。而且它定义于标准库中,如下:
enum Option<T> {
None,
Some(T),
}
你不需要将其显示的引入作用域。另外,它的成员也是如此,可以不需要Option::
前缀来直接使用Some
和None
。即便如此Option
也仍是有效的枚举,Some(T)
和None
仍是Option
的成员。
let x: i8 = 5;
let y: Option<i8> = Some(5);
let sum = x + y; // 这里将报错
事实上,这里 Rust
不知道如何将 Option<i8>
与i8
相加,因为它们的类型不同。