rust 初探 -- 枚举和模式匹配
定义枚举
rust
复制代码
enum IpAddrKind {
// 将数据附加到枚举的变体中
// - 不需要额外使用 struct
// - 每个变体可以拥有不同的类型以及关联的数据量
V4(String),
V6(String),
}
rust
复制代码
enum IpAddrKind {
a,
b(String),
c{x: i32, y: i32},
}
impl IpAddrKind {
fn call(&self) {}
}
fn main() {
let aa = IpAddrKind::a;
let bb = IpAddrKind::b(String::from("hello"));
let cc = IpAddrKind::c { x: 12, y: 21 };
bb.call();
}
Option 枚举
- 定义在标注库中,在 Prelude(预导入模块)中
rust 没有 Null
- Null 的问题:当你尝试像使用非 Null 值那样使用 Null 值的时候,就会引起某种错误
- Null 的作用:因某种原因而变为无效或缺失的值(Option)
Option 的优点
- Option 和 T 是不同的类型,不可以把 Option 直接当作 T
- 若想使用 Option 中的 T,必须把它转换成 T,避免了错误使用 null 进行操作(非Option 的肯定不是空的,否则就需要转换)
示例:
rust
复制代码
fn main() {
let x: i8 = 5;
let y: Option<i8> = Some(5);
//将 Option<T> 中的 T 转换成 T
let yy = y.expect("get Option<i8> fail");
let sum = x + yy;
println!("{}", sum)
}
match
- 允许一个值与一系列模式进行匹配,并执行匹配的模式对应的代码(示例)
rust
复制代码
enum Num {
One,
Two,
Three,
}
fn value_in_cents(num: Num) -> u8 {
// 依次匹配
match num {
Num::One => {
println!("match One");
1
},
Num::Two => 2,
Num::Three => 3,
}
}
fn main() {
let num = Num::One;
println!("{}", value_in_cents(num))
}
- 绑定值的模式:匹配的分支可以绑定到被匹配对象的部份值,可以从 enum 变体中提取值
rust
复制代码
#[derive(Debug)]
enum Name {
Tim,
Hope,
}
enum Num {
One,
Two,
Three(Name),
}
fn value_in_cents(num: Num) -> u8 {
// 依次匹配
match num {
Num::One => {
println!("match One");
1
},
Num::Two => 2,
Num::Three(name) => {
println!("three name is: {:#?}", name);//three name is: Hope
3
},
}
}
fn main() {
let num = Num::Three(Name::Hope);
println!("{}", value_in_cents(num)) // 3
}
匹配 Option
rust
复制代码
fn main() {
let five = Some(5);
let six = plus_one(five);
let none = plus_one(None);
// println!("{}, {}", six, none);
}
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
None => None,
Some(i) => Some(i+1),
}
}
- match 匹配必须穷举所有的可能性(会在编译时检查),如果不需要处理,可以使用通配符"_"替代:
rust
复制代码
fn main() {
let v = 0u8;
match v {
1 => println!("one"),
2 => println!("two"),
_ => (),
}
}
if let
- 处理只关注一种匹配,而忽略其他匹配的情况
- 更少的代码,更少的缩进,更少的模版代码
- 但是放弃了穷举的可能
rust
复制代码
fn main() {
let v = 0u8;
match v {
2 => println!("two"),
_ => println!("other"),
}
// 等效于上面的逻辑
if let 2 = v {
println!("two");
} else {
println!("other");
}
}