喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=^・ω・^=)
18.2.1. 模式的两种形式
模式有两种形式:
- 可辩驳的(可失败的)
- 无可辩驳的(不可失败的),可以把它理解为不会失败的,怎么写都会成功
其中能匹配任何可能传递的值的模式:无可辩驳的。看个例子:
rust
let x = 5;
这个语句是不可能失败的,因为x
能匹配表达式右侧所有可能的返回值。
对于某些可能的值,无法进行匹配的模式:可辩驳的。举个例子:
rust
if let Some(x) = a_value
如果右边的值是None
的话就会发生不匹配的情况。
函数参数、let
语句、for
循环只接受无可辩驳模式。看例子:
rust
let a:Option<i32> = Some(5);
let Some(x) = a;
Some(x) = a
是可辩驳的 (因为有可能出现None
的情况),但是let
语句只接受无可辩驳 模式,所以编译器会报错。那么怎么修改呢?使用if let
即可:
rust
let a:Option<i32> = Some(5);
if let Some(x) = a {
// ...
}
if let
和while let
支持可辩驳 和无可辩驳 模式。实际上,如果在if let
和while let
中使用无可辩驳模式编译器会发出警告,因为存在可能的失败。看个例子:
rust
if let x = 5 {
println!("{x}");
};
输出:
$ cargo run
Compiling patterns v0.1.0 (file:///projects/patterns)
warning: irrefutable `if let` pattern
--> src/main.rs:2:8
|
2 | if let x = 5 {
| ^^^^^^^^^
|
= note: this pattern will always match, so the `if let` is useless
= help: consider replacing the `if let` with a `let`
= note: `#[warn(irrefutable_let_patterns)]` on by default
warning: `patterns` (bin "patterns") generated 1 warning
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.39s
Running `target/debug/patterns`
5
编译器会报警"irrefutable if-let
pattern"。因为在一个可辩驳 的模式里使用无可辩驳模式是没有任何意义的。
基于这些概念,我们想一下match
表达式的分支:除了最后一个分支以外应该都是可辩驳的,而最后一个分支应该是无可辩驳的,因为这个分支需要匹配所有的剩余情况。