Update Chapter 18

This commit is contained in:
Aaran Xu 2022-01-23 23:58:50 +08:00
parent 1c019b8b8f
commit a81ae58322
3 changed files with 13 additions and 8 deletions

View File

@ -108,7 +108,7 @@ c is at index 2
### `let` 语句
在本章之前,我们只明确的讨论过通过 `match``if let` 使用模式,不过事实上也在别地方使用过模式,包括 `let` 语句。例如,考虑一下这个直白的 `let` 变量赋值:
在本章之前,我们只明确的讨论过通过 `match``if let` 使用模式,不过事实上也在别地方使用过模式,包括 `let` 语句。例如,考虑一下这个直白的 `let` 变量赋值:
```rust
let x = 5;
@ -120,7 +120,7 @@ let x = 5;
let PATTERN = EXPRESSION;
```
`let x = 5;` 这样的语句中变量名位于 `PATTERN` 位置,变量名不过是形式特别朴素的模式。我们将表达式与模式比较,并为任何找到的名称赋值。所以例如 `let x = 5;` 的情况,`x` 是一个模式代表 “将匹配到的值绑定到变量 x”。同时因为名称 `x` 是整个模式,这个模式实际上等于 “将任何值绑定到变量 `x`,不管值是什么”。
`let x = 5;` 这样的语句中变量名位于 `PATTERN` 位置,变量名不过是形式特别朴素的模式。我们将表达式与模式比较,并为任何找到的名称赋值。所以例如 `let x = 5;` 的情况,`x` 是一个表示“将匹配到的值绑定到变量 x” 的模式。同时因为名称 `x` 是整个模式,这个模式实际上等于 “将任何值绑定到变量 `x`,不管值是什么”。
为了更清楚的理解 `let` 的模式匹配方面的内容,考虑示例 18-4 中使用 `let` 和模式解构一个元组:
@ -153,7 +153,7 @@ error[E0308]: mismatched types
found type `(_, _)`
```
如果希望忽略元组中一个或多个值,也可以使用 `_``..`,如 [“忽略模式中的值”][ignoring-values-in-a-pattern] 部分所示。如果问题是模式中有太多的变量,则解决方法是通过去掉变量使得变量数与元组中元素数相等。
如果希望忽略元组中一个或多个值,也可以使用 `_``..`,如 [“忽略模式中的值”][ignoring-values-in-a-pattern]<!-- ignore --> 部分所示。如果问题是模式中有太多的变量,则解决方法是通过去掉变量使得变量数与元组中元素数相等。
### 函数参数
@ -191,4 +191,4 @@ fn main() {
现在我们见过了很多使用模式的方式了,不过模式在每个使用它的地方并不以相同的方式工作;在一些地方,模式必须是 *irrefutable* 的,意味着他们必须匹配所提供的任何值。在另一些情况,他们则可以是 refutable 的。接下来让我们讨论这两个概念。
[ignoring-values-in-a-pattern]:
ch18-03-pattern-syntax.html#ignoring-values-in-a-pattern
ch18-03-pattern-syntax.html#忽略模式中的值

View File

@ -14,7 +14,7 @@ let Some(x) = some_option_value;
<span class="caption">示例 18-8: 尝试在 `let` 中使用可反驳模式</span>
如果 `some_option_value` 的值是 `None`,其不会成功匹配模式 `Some(x)`,表明这个模式是可反驳的。然而 `let` 语句只能接受不可反驳模式因为代码不能通过 `None` 值进行有效的操作。Rust 会在编译时抱怨我们尝试在要求不可反驳模式的地方使用可反驳模式:
`some_option_value` 的值是 `None`,则不会成功匹配模式 `Some(x)`,表明这个模式是可反驳的。然而 `let` 语句只能接受不可反驳模式因为代码不能通过 `None` 值进行有效的操作。Rust 会在编译时抱怨我们尝试在要求不可反驳模式的地方使用可反驳模式:
```text
error[E0005]: refutable pattern in local binding: `None` not covered
@ -24,7 +24,7 @@ error[E0005]: refutable pattern in local binding: `None` not covered
| ^^^^^^^ pattern `None` not covered
```
因为我们没有覆盖(也不可能覆盖!)到模式 `Some(x)` 的每一个可能的值, 所以 Rust 会合理地抗议
因为我们没有覆盖(也无法覆盖!)模式 `Some(x)` 的每一个可能的有效值Rust 理所当然地产生了编译器错误
为了修复在需要不可反驳模式的地方使用可反驳模式的情况,可以修改使用模式的代码:不同于使用 `let`,可以使用 `if let`。如此,如果模式不匹配,大括号中的代码将被忽略,其余代码保持有效。示例 18-9 展示了如何修复示例 18-8 中的代码。
@ -37,7 +37,12 @@ if let Some(x) = some_option_value {
<span class="caption">示例 18-9: 使用 `if let` 和一个带有可反驳模式的代码块来代替 `let`</span>
我们给了代码一个得以继续的出路!这段代码可以完美运行,尽管这意味着我们不能再使用不可反驳模式并免于收到错误。如果为 `if let` 提供了一个总是会匹配的模式,比如示例 18-10 中的 `x`,编译器会给出一个警告:
我们给了代码一个得以继续的出路!这段代码完全有效,尽管这意味着我们不能在避免产生错误的情况下使用无可辩驳的模式。如果为 `if let` 提供了一个总是会匹配的模式,比如示例 18-10 中的 `x`,编译器会给出一个警告:
Weve given the code an out! This code is perfectly valid, although it means we
cannot use an irrefutable pattern without receiving an error. If we give `if
let` a pattern that will always match, such as `x`, as shown in Listing 18-10,
the compiler will give a warning.
```rust,ignore
if let x = 5 {

View File

@ -590,7 +590,7 @@ match msg {
上例会打印出 `Found an id in range: 5`。通过在 `3..=7` 之前指定 `id_variable @`,我们捕获了任何匹配此范围的值并同时测试其值匹配这个范围模式。
第二个分支只在模式中指定了一个范围,分支相关代码代码没有一个包含 `id` 字段实际值的变量。`id` 字段的值可以是 10、11 或 12不过这个模式的代码并不知情也不能使用 `id` 字段中的值,因为没有将 `id` 值保存进一个变量。
第二个分支只在模式中指定了一个范围,分支相关代码没有一个包含 `id` 字段实际值的变量。`id` 字段的值可以是 10、11 或 12不过这个模式的代码并不知情也不能使用 `id` 字段中的值,因为没有将 `id` 值保存进一个变量。
最后一个分支指定了一个没有范围的变量,此时确实拥有可以用于分支代码的变量 `id`,因为这里使用了结构体字段简写语法。不过此分支中没有像头两个分支那样对 `id` 字段的值进行测试:任何值都会匹配此分支。