喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)
18.1.1. 什么是模式
模式(pattern) 是Rust里的一种特殊的语法,用于匹配复杂和简单类型的结构。
将模式与匹配表达式和其他构造结合使用,可以更好地控制程序的控制流。
模式由以下元素(的一些组合)组成:
- 字面值
- 解构的数组、
enum
、struct
和tuple
- 变量
- 通配符
- 占位符
想要使用模式,需要将其与某个值进行比较:如果模式匹配,就可以在代码中使用这个值的相应部分。
18.1.2. match
的Arm
Arm
(分支)就可以使用模式。它的形式是:
match VALUE {PATTERN => EXPRESSION,PATTERN => EXPRESSION,PATTERN => EXPRESSION,
}
match
的要求是详尽(尽可能包含所有可能性),必须把所有的可能性写全。
在match
还经常用到_
,它会匹配任何东西。它并不会绑定到变量上。它通常用于match
的最糊一个分支,或用于忽略某个值。
如果想要看更详细的介绍,可以去 6.3. 控制流运算符-match
18.1.3. if let
表达式
if let
表达式可以看作是match
表达式只匹配一种可能性的形式。
它可选地可以拥有,包括:
else if
else
else if let
if let
相比于match
的缺点在于不会检查穷尽性,如果我们省略了最后一个else
块并因此错过了对某些情况的处理,编译器将不会提醒我们可能的逻辑错误。看个例子:
fn main() {let favorite_color: Option<&str> = None;let is_tuesday = false;let age: Result<u8, _> = "34".parse();if let Some(color) = favorite_color {println!("Using your favorite color, {color}, as the background");} else if is_tuesday {println!("Tuesday is green day!");} else if let Ok(age) = age {if age > 30 {println!("Using purple as the background color");} else {println!("Using orange as the background color");}} else {println!("Using blue as the background color");}
}
如果用户指定最喜欢的颜色,则该颜色将用作背景。如果没有指定最喜欢的颜色并且今天是星期二,则背景颜色为绿色。否则,如果用户将他们的年龄指定为字符串,并且我们可以成功将其解析为数字,则颜色为紫色或橙色,具体取决于数字的值。如果这些条件都不适用,则背景颜色为蓝色。
这种条件结构使我们能够支持复杂的需求。使用我们这里的硬编码值,此示例将打印 Using purple as the background color
。
你可以看到, if let
也可以采用与match
相同的方式引入阴影变量: if let Ok(age) = age
行引入了一个新的阴影age
变量,其中包含Ok
变量内的值。这意味着我们需要将if age > 30
条件放置在该块中:我们不能将这两个条件组合成 if let Ok(age) = age && age > 30
。我们想要与 30 进行比较的阴影age
在新范围以大括号{
开头之前才有效。
其余详细内容可见 6.4. 简单的控制流-if let
18.1.4. while let
条件循环
while let
和if let
有点相似,只要模式继续满足匹配的条件,那它允许while
循环一直运行。
看个例子:
let mut stack = Vec::new();stack.push(1);
stack.push(2);
stack.push(3);while let Some(top) = stack.pop() {println!("{top}");
}
此示例打印 3、2,然后打印 1。 pop
方法从向量中取出最后一个元素并返回Some(value)
。如果向量为空, pop
返回None
。只要pop
返回Some
, while
循环就会继续运行其块中的代码。当pop
返回None
时,循环停止。我们可以使用while let
将每个元素从堆栈中弹出。
18.1.5. for
循环
for
循环是Rust中Rust中最常见的循环。for
循环中,模式就是紧随for
关键字后的值。
在for
循环中,直接跟在关键字for
后面的值是一个模式。例如,在for x in y
中, x
是模式。下面的例子演示了如何在for
循环中使用模式来解构或分解元组作为for
循环的一部分:
let v = vec!['a', 'b', 'c'];for (index, value) in v.iter().enumerate() {println!("{value} is at index {index}");
}
输出:
a is at index 0
b is at index 1
c is at index 2
其余信息可见 3.6. 控制流:循环
18.1.6. let
语句
let
语句也是模式,其写法规范是:
let PATTERN = EXPRESSION;
看个例子:
let (x, y, z) = (1, 2, 3);
我们将元组与模式进行匹配。 Rust 比较值(1, 2, 3)
到模式(x, y, z)
并看到该值与模式匹配,因此 Rust 将1
绑定到x
, 2
绑定到y
, 3
绑定到z
。你可以将此元组模式视为其中嵌套了三个单独的变量模式。
18.1.7. 函数参数
函数的参数也可以是模式,看个例子:
fn foo(x: i32) {// ...
}
x
部分是一个模式。
正如我们对let
所做的那样,我们可以将函数参数中的元组与模式进行匹配。如下例:
fn print_coordinates(&(x, y): &(i32, i32)) {println!("Current location: ({x}, {y})");
}fn main() {let point = (3, 5);print_coordinates(&point);
}