枚举
定义
Variants can be accessed through :: notation, ex. Day::Sunday
通过双冒号 :: 访问枚举成员
⭐️ Each enum variant can have,
- No data (unit variant)
- Unnamed ordered data (tuple variant)
- Named data (struct variant)
枚举成员的类型:
- 单元结构体
- 元组结构体
- 类
C结构体
示例:
enum FlashMessage {Success, // 1.单元类型成员Warning { category: i32, message: String }, // 2.结构体类型成员Error(String), // 3.元组类型成员}fn main() {// 1.单元类型成员let mut form_status = FlashMessage::Success;print_flash_message(form_status);// 2.结构体类型成员form_status = FlashMessage::Warning {category: 2,message: String::from("Field X is required"),};print_flash_message(form_status);3.元组类型成员form_status = FlashMessage::Error(String::from("Connection Error"));print_flash_message(form_status);}fn print_flash_message(m: FlashMessage) {// 对于枚举的模式匹配match m {FlashMessage::Success => println!("Form Submitted correctly"),FlashMessage::Warning { category, message } =>// 用相同的属性名解构{println!("Warning : {} - {}", category, message)}FlashMessage::Error(msg) => println!("Error : {}", msg),}}
枚举的方法
可以使用impl来为枚举上定义方法:
fn main() {#[derive(Debug)]enum Message {Quit,Move { x: i32, y: i32 },Write(String),ChangeColor(i32, i32, i32),}impl Message {fn call(&self) {println!("{:?}", self)}}let m = Message::Write(String::from("hello"));m.call();}
方法中的self指向变量m
枚举也可以有关联函数
Option枚举
空值的问题在于当你尝试像一个非空值那样使用一个空值,会出现某种形式的错误。
然而,空值尝试表达的概念仍然是有意义的:空值是一个因为某种原因目前无效或缺失的值。
Rust 并没有空值,不过它确实拥有一个可以编码存在或不存在概念的枚举。这个枚举是 Option<T>,而且它定义于标准库中,如下:
enum Option<T> {Some(T),None,}
Option<T>枚举包含在了prelude之中,可以直接使用**Option<T>**和其成员**Some()**和**None**
如果只使用None而不是Some,需要告诉Rust``Option<T>是什么类型的
Option<T>和T(这里T可以是任何类型)是不同的类型,因此即使Some()中有值,也不能直接使用,而是需要使用**match**表达式对Some()和None指定各自的处理代码。这样就能考虑到值存在和不存在的情况,而不是直接假设值存在
match控制流
=>运算符将模式和将要运行的代码分开
每个分支相关联的代码是一个表达式(即花括号这样的语句块叫做表达式),而表达式的结果值将作为整个match表达式的返回值。
Rust中的匹配是穷尽的(exhaustive):必须穷举到最后的可能性来使代码有效。
**_** 通配符
示例:
let some_u8_value = 0u8;match some_u8_value {1 => println!("one"),3 => println!("three"),_ => (),}
if let语句
if let用来处理只匹配一个模式的值而忽略其他模式的情况,是match的一个语法糖
if let没有返回值
这会失去match强制要求的穷尽性检查
if let获取通过等号分隔的一个模式和一个表达式。
示例:
if let Some(3) = some_u8_value {println!("three");}
可以搭配**else**语句来用,用于匹配所有其他情况,相当于match中的通配符_
示例:
let mut count = 0;if let Coin::Quarter(state) = coin {println!("State quarter from {:?}!", state);} else {count += 1;}
