x-i18n: generated_at: “2026-03-01T14:55:44Z” model: gemini-3-flash-preview provider: google-gemini-cli source_hash: 59e75e2673e39e4006f1f07b5c12a9df5b5c0d33f6f2d0515f756ca6c134a01c source_path: ch19-02-refutability.md workflow: 16
可反驳性:模式是否可能匹配失败 (Refutability: Whether a Pattern Might Fail to Match)
Refutability: Whether a Pattern Might Fail to Match
模式有两种形式:可反驳的 (refutable) 和不可反驳的 (irrefutable)。对于任何可能的传入值都能匹配成功的模式是“不可反驳的”。例如 let x = 5; 语句中的 x ,因为 x 可以匹配任何内容,因此不会匹配失败。对于某些可能的值会匹配失败的模式是“可反驳的”。例如 if let Some(x) = a_value 表达式中的 Some(x) ,因为如果 a_value 变量中的值是 None 而不是 Some ,模式 Some(x) 就不会匹配成功。
Patterns come in two forms: refutable and irrefutable. Patterns that will match
for any possible value passed are irrefutable. An example would be x in the
statement let x = 5; because x matches anything and therefore cannot fail
to match. Patterns that can fail to match for some possible value are
refutable. An example would be Some(x) in the expression if let Some(x) = a_value because if the value in the a_value variable is None rather than
Some, the Some(x) pattern will not match.
函数参数、 let 语句和 for 循环只能接受不可反驳的模式,因为当值不匹配时,程序无法执行任何有意义的操作。 if let 和 while let 表达式以及 let...else 语句接受可反驳和不可反驳的模式,但编译器会针对不可反驳的模式发出警告,因为根据定义,它们是旨在处理可能失败的情况的:条件结构的意义在于它能够根据成功或失败执行不同的操作。
Function parameters, let statements, and for loops can only accept
irrefutable patterns because the program cannot do anything meaningful when
values don’t match. The if let and while let expressions and the
let...else statement accept refutable and irrefutable patterns, but the
compiler warns against irrefutable patterns because, by definition, they’re
intended to handle possible failure: The functionality of a conditional is in
its ability to perform differently depending on success or failure.
通常情况下,你不需要担心可反驳模式和不可反驳模式之间的区别;然而,你确实需要熟悉可反驳性的概念,以便在错误消息中看到它时做出响应。在这些情况下,你需要根据代码的预期行为,更改模式或使用该模式的结构。
In general, you shouldn’t have to worry about the distinction between refutable and irrefutable patterns; however, you do need to be familiar with the concept of refutability so that you can respond when you see it in an error message. In those cases, you’ll need to change either the pattern or the construct you’re using the pattern with, depending on the intended behavior of the code.
让我们看一个例子,看看当我们尝试在 Rust 要求不可反驳模式的地方使用可反驳模式时会发生什么,反之亦然。示例 19-8 显示了一个 let 语句,但对于模式,我们指定了 Some(x) ,这是一个可反驳模式。正如你所料,这段代码将无法编译。
Let’s look at an example of what happens when we try to use a refutable pattern
where Rust requires an irrefutable pattern and vice versa. Listing 19-8 shows a
let statement, but for the pattern, we’ve specified Some(x), a refutable
pattern. As you might expect, this code will not compile.
{{#rustdoc_include ../listings/ch19-patterns-and-matching/listing-19-08/src/main.rs:here}}
如果 some_option_value 是 None 值,它将无法匹配模式 Some(x) ,这意味着该模式是可反驳的。然而, let 语句只能接受不可反驳的模式,因为对于 None 值,代码无法执行任何有效的操作。在编译时,Rust 会抱怨我们尝试在需要不可反驳模式的地方使用了可反驳模式:
If some_option_value were a None value, it would fail to match the pattern
Some(x), meaning the pattern is refutable. However, the let statement can
only accept an irrefutable pattern because there is nothing valid the code can
do with a None value. At compile time, Rust will complain that we’ve tried to
use a refutable pattern where an irrefutable pattern is required:
{{#include ../listings/ch19-patterns-and-matching/listing-19-08/output.txt}}
因为我们没有(也无法!)用 Some(x) 模式覆盖每一个有效值,所以 Rust 理所当然地产生了一个编译器错误。
Because we didn’t cover (and couldn’t cover!) every valid value with the
pattern Some(x), Rust rightfully produces a compiler error.
如果我们有一个需要不可反驳模式的地方却使用了可反驳模式,我们可以通过更改使用该模式的代码来修复它:不使用 let ,我们可以使用 let...else 。然后,如果模式不匹配,花括号中的代码将处理该值。示例 19-9 展示了如何修复示例 19-8 中的代码。
If we have a refutable pattern where an irrefutable pattern is needed, we can
fix it by changing the code that uses the pattern: Instead of using let, we
can use let...else. Then, if the pattern doesn’t match, the code in the curly
brackets will handle the value. Listing 19-9 shows how to fix the code in
Listing 19-8.
#![allow(unused)]
fn main() {
{{#rustdoc_include ../listings/ch19-patterns-and-matching/listing-19-09/src/main.rs:here}}
}
我们给了代码一个出路!这段代码是完全有效的,尽管这意味着我们不能在不接收警告的情况下使用不可反驳模式。如果我们给 let...else 一个总是会匹配的模式,例如 x ,如示例 19-10 所示,编译器会给出警告。
We’ve given the code an out! This code is perfectly valid, although it means we
cannot use an irrefutable pattern without receiving a warning. If we give
let...else a pattern that will always match, such as x, as shown in Listing
19-10, the compiler will give a warning.
#![allow(unused)]
fn main() {
{{#rustdoc_include ../listings/ch19-patterns-and-matching/listing-19-10/src/main.rs:here}}
}
Rust 抱怨将 let...else 用于不可反驳模式没有意义:
{{#include ../listings/ch19-patterns-and-matching/listing-19-10/output.txt}}
由于这个原因,match 分支必须使用可反驳模式,除了最后一个分支,它应该使用不可反驳模式匹配任何剩余的值。Rust 允许我们在只有单个分支的 match 中使用不可反驳模式,但这种语法并不是特别有用,并且可以用更简单的 let 语句代替。
For this reason, match arms must use refutable patterns, except for the last
arm, which should match any remaining values with an irrefutable pattern. Rust
allows us to use an irrefutable pattern in a match with only one arm, but
this syntax isn’t particularly useful and could be replaced with a simpler
let statement.
既然你已经知道了在哪里使用模式以及可反驳和不可反驳模式之间的区别,让我们来看看所有可以用来创建模式的语法。
Now that you know where to use patterns and the difference between refutable and irrefutable patterns, let’s cover all the syntax we can use to create patterns.