6. 枚举
6.1 定义枚举
在rust中我们使用enum定义一个枚举,并且枚举使用大驼峰的命名方式,例如:
enum Color {
Red,
Green,
Blue,
}
那我们应该如何使用枚举呢?我们可以直接在定义好的枚举名后面使用::就可以访问到枚举内的数据,如下:
Color::Blue
我们还可以使用enum定义不同变体的枚举,例如:
#[derive(Debug)]
enum Color {
Red,
Green,
Blue,
RGB(u16, u16, u16), // 元祖结构体
Hex { input: String }, // 结构体
}
println!("{:#?}", Color::Hex { input: String::from("#000") });
println!("{:#?}", Color::RGB(255, 255, 255));
rust还为我们内置了Option枚举,用于处理一个不可靠的值,假如该值可能不存在,那我们可以使用该枚举来定义值;当我们完全能确认我们定义的值存在,那就没有必要使用,后面我们会结合着match使用。例如:
let _not_confirmed_value: Option<i8> = Some(1);
let _not_confirmed_value: Option<i8> = None;
6.2 为枚举定义方法
枚举和结构体一样,我们使用impl为其定义方法,如果第一个参数是&self表示需要生成实例后调用;否则我们只需要使用::调用即可。例如:
#[derive(Debug)]
enum Color {
Red,
Green,
Blue,
}
impl Color {
fn instance_fn(&self) {
println!("{:#?}", self);
}
fn static_fn() {
println!("{:#?}", Color::Red)
}
}
Color::static_fn(); // Red
let color = Color::Blue;
color.instance_fn(); //Blue
6.3 match匹配
当我们使用枚举类型,并且想要使用一个变量值去判断是否和其中的某一项相等,如果我们直接使用if去判断,会报错,这个时候就引出match,例如:
#[derive(Debug)]
enum Color {
Red,
Green,
Blue,
}
fn match_color(color: Color) {
match color {
Color::Blue => {
println!("{}", "蓝色")
}
Color::Green => {
println!("{}", "绿色")
}
Color::Red => {
println!("{}", "红色")
}
}
}
match_color(Color::Blue);
由于rust里面的match是穷尽匹配,所有我们需要把所有的每项列出来,这样会很麻烦,如果数据过多,这时我们可以使用通用匹配符号_,例如:
#[derive(Debug)]
enum Color {
Red,
Green,
Blue,
}
fn match_color(color: Color) {
match color {
Color::Blue => {
println!("{}", "蓝色")
}
_ => println!("其余颜色"), // 通配符
}
}
match_color(Color::Red);
我们刚刚提到的内置的Option枚举类型,我们可以使用match来对其进行匹配,例如:
fn add_one(value: Option<i8>) -> Option<i8> {
match value {
Option::Some(i) => Some(i + 1),
Option::None => None,
}
}
let num: Option<i8> = Some(5);
let num: Option<i8> = add_one(num);
println!("{:#?}", num) // Some(6)
上面我们使用Some(5)去匹配Some(i)依然能匹配上,这里因为i是i8的数字类型,和我们定义的变量相同,所以能够匹配上,否则就会匹配到None
6.4 if let匹配
如果我们只想匹配枚举中的一个项,而不想写通配符,这个时候我们就可以使用if let来匹配枚举,例如:
enum Color {
Red,
Green,
Blue,
}
let color: Color = Color::Blue;
if let Color::Blue = color {
println!("蓝色")
}