以下内容为本人学习过程中的记录笔记,其中可能存在不准确或错误,欢迎勘误及指正
枚举的基本操作
在Rust中,枚举类型是一种通过enum
关键字定义的特殊的类型,允许用户定义一个取值范围有限的变量
定义枚举
一个枚举可以包含一系列命名的值,这些值就被称为枚举成员(enumeration variant)
1 2 3 4 5 6 7 8 9 10 11 12
| enum Species { Human, Animal, Plant, }
fn main() { let john = Species::Human; let tom = Species::Animal; }
|
枚举类型作为自定义数据类型,和其他的数据类型一样,枚举变量也可以通过函数进行传递或作为结构体字段类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| enum Species { Human, Animal, Plant, }
struct Earth { leader: Species, member: String, }
fn main() { let john = Species::Human; let tom = Species::Animal;
sleep(john); sleep(tom); sleep(Species::Animal); }
fn sleep(species: Species) {}
|
枚举成员可以是一个简单的标识符,也可以包含数据或者匿名结构体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| enum Species { Human(String), Animal(String), Plant(String), Alien { name: String, attitude: String }, }
fn main() { let john = Species::Human("Male".to_string()); let tom = Species::Animal("Cat".to_string()); let tiga = Species::Alien { name: "Ultraman".to_string(), attitude: "Friendly".to_string(), }; }
|
枚举方法
和结构体类似,枚举也可以使用impl
定义其关联的方法
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
| enum Species { Human(String), Animal(String), Plant(String), Alien { name: String, attitude: String }, }
impl Species { fn war(&self) { match self { Species::Alien { name, attitude } if attitude == "Hostile" => { println!("{} is a threat, Start War!", name); } _ => { println!("Friendly!"); }, } } }
fn main() { let tiga = Species::Alien { name: "Ultraman".to_string(), attitude: "Friendly".to_string(), }; let thanos = Species::Alien { name: "Eternals".to_string(), attitude: "Hostile".to_string(), }; tiga.war(); thanos.war(); }
|
枚举的解构
当我们想使用枚举中的值或针对特定枚举执行相应的操作时,就需要通过模式匹配(pattern matching)来解构枚举。具体来说,可以使用match
或if let
表达式,将枚举变量与每个可能的值进行比较,并执行相应的操作
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 36 37 38 39 40 41 42
| enum Species { Quit, Human(String), Animal(String), Plant(String), }
fn main() { let flag = Species::Quit; let person = Species::Human("john".to_string()); let cat = Species::Animal("tom".to_string()); let chaos = Species::Human("jeff".to_string());
let person_name = match person { Species::Human(name) => name, Species::Plant(name) => name, Species::Animal(name) => name, Species::Quit => "No Person".to_string(), };
let chaos_name = if let Species::Plant(name) = chaos { name } else if let Species::Animal(name) = chaos { name } else { "chaos Unknown!".to_string() };
let animal_name = match cat { Species::Animal(name) => Some(name), _ => None, };
if let Species::Quit = flag {}
println!("{}", person_name); println!("{:?}", animal_name); println!("{}", chaos_name); }
|
由上面例子可以看出来,使用match
对枚举进行解构时需列举所有的可能情况,但我们也可以使用_
通配符来简化匹配;if let
则只适用于匹配单个模式的情况,但可配合使用else
和else if let
来匹配多个模式