解构的意思是将原来的结构肢解为单独的、局部的、原始的部分
Rust中的模式解构可以出现在let、match、if let、while let、函数调用、闭包调用等情景中。
什么是模式解构
fn main() {
let tuple = (1_i32, false, 3f32); //将三个元素组合在一起,构造成一个元组
let (h, c, t) = tuple; //模式解构:把一个元组拆解开来,分别与三个变量绑定
println!("{}, {}, {}", h, c, t)
}
Rust中模式解构的元组:怎么将一个数据解构组合起来就怎么将它拆开来
struct T1 (i32, char);
struct T2 {
item1: T1,
item2: bool,
}
fn main(){
let x = T2 {
item1: T1(0, 'A'),
item2: false,
};
let T2 {
item1: T1(value1, value2),
item2: value3,
} = x;
println!("{} {} {}", value1, value2, value3)
}
模式解构时可以使用占位符_匹配1个值,…匹配多个值
fn main() {
let x = (1, 2, 3);
let (a, _, _) = x; // 模式解构
println!("{}", a);
let (.., a) = x; // 模式解构
println!("{}", a);
}
match
match是一个控制流运算符,它允许我们将一个值与一系列的模式相比较并根据相匹配的模式执行相应的代码。模式可由字面值、变量、通配符和许多其他内容组成。
enum Direction {
East, West, South, North
}
fn print(x: Direction)
{
match x { //按顺序与每一个分支的模式相比较
Direction::East => {
println!("East");
}
Direction::West => {
println!("West");
}
Direction::South => {
println!("South");
}
Direction::North => {
println!("North");
}
}
}
fn main() {
let x = Direction::East;
print(x);
}
exhaustive
Rust要求match需要对所有情况做完整的、无遗漏的匹配,如果漏掉了某些情况,是不能编译通过的。exhaustive意思是无遗漏的、穷尽的、彻底的、全面的。exhaustive是Rust模式匹配的重要特点。
也就是说,如果有任何一个情况没有用上,编译就会通不过,如下
enum Direction {
East, West, South, North
}
fn print(x: Direction)
{
match x { //error[E0004]: non-exhaustive patterns: `North` not covered
Direction::East => println!("East");
Direction::West => println!("West");
Direction::South => {
println!("South");
}
// Direction::North => {
// println!("North");
// }
}
}
fn main() {
let x = Direction::East;
print(x);
}
match与符号
_与match
_ 模式会匹配所有的值。通过将其放置于其他分支之后,_ 将会匹配所有之前没有指定的可能的值
fn match_u8(x:u8){
match x {
1 => println!("One"),
3 => println!("three"),
5 => println!("five"),
7 => println!("seven"),
_ => println!("Other"),
}
}
fn main() {
match_u8(2u8); //Other
match_u8(11u8); //Other
}
…=与match
…=表示一个闭区间范围
fn match_u8(x:i32){
match x {
0 ..= 99 => println!("0 ~ 99"),
111 ..= 1000 => println!("111 ~ 1000"),
_ => println!("Other"),
}
}
fn main() {
match_u8(0);
match_u8(99);
match_u8(100); //Other
}
| 与match
或运算符|匹配多个条件
fn match_u8(x:i32){
match x {
0 ..= 99 | 111 ..= 1000 => println!("0 ~ 99, 111 ~ 1000"),
_ => println!("Other"),
}
}
fn main() {
match_u8(0);
match_u8(99);
match_u8(120);
}
if与match
fn main() {
let x = 10;
match x {
i if i > 5 =>println!("bigger"),
i if i <=5 => println!("smaller or equal"),
_ => unreachable!(),
}
}
总结:
- match一个枚举,绑定其中的值到一个变量,接着根据其值匹配代码。跟switch相似
- march只关心一个情况里面场景
- 如果我们进行匹配的值同时符合好几条分支,那么总会执行第一条匹配成功的分支,忽略其他分支
match与变量绑定
@与match
@绑定变量:@前面是新声明的变量,后面是需要绑定的模式
fn main(){
let x = 11;
match x {
_i @ 1 ..= 5 =>println!("the range of [1, 5]"),
_ => println!("nothing")
}
}
参考:《深入浅出rust》