此篇假定读者了解枚举的作用,如你还没有接触枚举或者对枚举的应用不太了解的话,建议先补完基础后再看。
另外枚举涉及到Rust的一个特别功能——模式匹配,为了更好理解,请仔细看完本章的#更近一步这一节。
使用enum
声明定义枚举
枚举的命名规范和结构体命名规范一样,使用大驼峰命名法。
一个简单枚举定义如下:
1 2 3 4
| enum Gender { Male, Female, }
|
更进一步
Rust的枚举并不局限于表示类型,还可以嵌入结构体和另一个枚举(如果嵌套自己会导致无法确定类型大小):
1 2 3 4 5 6 7 8 9
| enum Signal { None, Num(i128), Bool(bool), Info { id: u64, age: u8, } }
|
使用match
匹配
说完定义枚举,接下来该介绍如何使用枚举了。
回顾一下,我在控制流一章中只介绍了match
值匹配和条件匹配,现在来说一下类型匹配。
一个简单的例子如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| enum Num { One, Two, Three, }
fn convert(num: Num) -> u8 { return match num { Num::One => 1, Num::Two => 2, Num::Three => 3, };
}
fn main() { let num = Num::One; let num = convert(num); }
|
而对于嵌入结构体的枚举,可以这样使用match
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| enum Signal { None, Bool(bool), Info { id: u64, age: u8, } }
fn pln(sig: Signal) { match sig { Signal::None => println!("None!"), Signal::Bool(bl) => println!("{}", bl), Signal::Info{ id: iid, age } => { println!("id={}\nage={}", iid, age); } } }
fn main() { let arr = [ Signal::None, Signal::Bool(true), Signal::Info{ id: 0, age: 18 }, ];
for sig in arr { pln(sig); } }
|
输出:
上面对枚举Num
使用match
进行的操作又被称为匹配。
if let
简洁匹配
match
匹配需处理所有可能的情况,如果只需匹配特定的情况,则可以使用if let
简洁匹配。
例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| enum Signal { None, Bool(bool), Info { id: u64, age: u8, } }
fn pln_bool(sig: Signal) { if let Signal::Bool(bl) = sig { println!("这个信号为Signal::Bool(bool), 其中bool值为{}", bl); } }
|
while let
循环匹配
与if let
类似,略。
let
匹配
使用let
声明并定义变量时,可以使用匹配定义语法(非官方术语):
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| let nu = (12, 32.);
let (nu1, nu2: f64) = nu;
let nu = [12, 34]; let [nu1, nu2] = nu;
struct Nu { t1: i32, t2: i64 } let nu = Nu{ t1: 12, t2: 34 };
let Nu{ t1: nu1, t2: nu2} = nu;
|
C风格用法
同C一样,Rust的普通枚举(高级枚举未测试)也有辨别值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| enum Num { Zero, One, Two, Three, Five, }
enum Num2 { Zero, Two = 2, One = 1, Three = 3, }
|
与C不同,要使用辨别值必须进行类型强转:
1 2
| let t1 = Num2::Two as i32;
|