枚举:
允许我们列举所有可能的值来定义一个类型。
如:
定义一个 IpAddrKind
枚举来表现这个概念并列出可能的 IP 地址类型,V4
和 V6
。这被称为枚举的 成员(variants):
enum IpAddrKind {
V4,
V6,
}
枚举值:
let four = IpAddrKind::V4;
let six = IpAddrKind::V6;
注意枚举的成员位于其标识符的命名空间中,并使用两个冒号分开。这么设计的益处是现在 IpAddrKind::V4
和 IpAddrKind::V6
都是 IpAddrKind
类型的。
fn route(ip_kind: IpAddrKind) {}
现在可以使用任一成员来调用这个函数:
route(IpAddrKind::V4);
route(IpAddrKind::V6);
将数据附加到枚举的变体中:
enum IpAddr {
V4(String),
V6(String),
}
let home = IpAddr::V4(String::from("127.0.0.1"));
let loopback = IpAddr::V6(String::from("::1"));
优点:
- 直接将数据附加到枚举的每个成员上,这样就不需要一个额外的结构体
- 每个成员可以处理不同类型和数量的数据。
如:
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
struct Ipv4Addr {
// --snip--
}
struct Ipv6Addr {
// --snip--
}
enum IpAddr {
V4(Ipv4Addr),
V6(Ipv6Addr),
}
枚举成员中内嵌了多种多样的类型:
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
-
Quit
没有关联任何数据。 -
Move
类似结构体包含命名字段。 -
Write
包含单独一个String
。 -
ChangeColor
包含三个i32
。
为枚举定义方法:
例子:
impl Message {
fn call(&self) {
// 在这里定义方法体
}
}
let m = Message::Write(String::from("hello"));
m.call();