枚举
定义
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;
}