枚举(enum)
Rust的枚举非常强大,代表一系列子数据类型的集合。类似于Java风格的枚举。
最简单的枚举
// enums
enum Direction { // 四个方向
West,
North,
Sourth,
East,
}
元组结构体型的枚举
枚举元素是一种元组结构体。这样枚举元素就可以拥有字段了。
#[derive(Debug)]
enum IpAddr {
V4(String),
V6(String)
}
fn main() {
let ipv4 = IpAddr::V4(String::from("127.0.0.1"));
println!("{:?}",ipv4); // 打印:V4("127.0.0.1")
}
标准库std::net::IpAddr有如下类似的定义:
#[derive(Debug)]
struct IpAddrV4 {
// ...
}
#[derive(Debug)]
struct IpAddrV6 {
// ...
}
#[derive(Debug)]
enum IpAddr {
V4(IpAddrV4),
V6(IpAddrV6)
}
fn main() {
let ipv4 = IpAddr::V4(IpAddrV4{});
println!("{:?}",ipv4); // 打印:V4(IpAddrV4)
}
结构体型的枚举
枚举元素是一种结构体。
#[derive(Debug)]
enum IpAddr {
V4{x1:u8,x2:u8,x3:u8,x4:u8},
V6{x1:u16,x2:u16,x3:u16,x4:u16,x5:u16,x6:u16,x7:u16,x:8:u16}
}
fn main() {
let ipv4 = IpAddr::V4{x1:127,x2:0,x3:0,x4:1};
println!("{:?}",ipv4);
}
枚举元素可以是不同的复合数据类型。
例:如下,V4、V6的字段数不同,是两种不同类型。
enum IpAddr {
V4(u8,u8,u8,u8),
V6(u8,u8,u8,u8,u8,u8)
}
fn main() {
let ipv4 = IpAddr::V4(127,0,0,1);
println!("{:?}",ipv4); // 打印:V4(127, 0, 0, 1)
}
由此可见Rust的enum子类型可以拥有不同的类型。这也是Rust比Java enum强大的地方。
Rust enum的每一个元素都可以支持不同类型的参数。
例:如下枚举,每个子类型都拥有不同结构的复合类型。
// enums
enum Message {
Quit,
ChangeColor(i32, i32, i32),
Move { x: i32, y: i32 },
Write(String),
}
说明:Message的4个元素是4中不同类型。
访问枚举元素
使用::
来访问枚举元素。
let direction: Direction = Direction::West
// 或
let message: Message = Message::Move { x: 3, y: 4 };
访问枚举类型内部的值需要使用模式匹配。
enum SpecialPoint {
Point(i32, i32),
Special(String),
}
fn main() {
let sp = SpecialPoint::Point(0, 0);
match sp {
SpecialPoint::Point(x, y) => {
println!("I'am SpecialPoint(x={}, y={})", x, y);
}
SpecialPoint::Special(why) => {
println!("I'am Special because I am {}", why);
}
}
}
更多关于枚举的模式匹配,请参看本书模式匹配
一节中的内容。