update ch06

pull/683/head
KaiserY 2 years ago
parent fe175e6e15
commit d33ef24ed4

@ -2,6 +2,6 @@
> [ch06-00-enums.md](https://github.com/rust-lang/book/blob/main/src/ch06-00-enums.md) > [ch06-00-enums.md](https://github.com/rust-lang/book/blob/main/src/ch06-00-enums.md)
> <br> > <br>
> commit c76f1b4d011fe59fc4f5e6f258070fc40d9921e4 > commit bb7e429ad6b59d9a0c37db7434976364cbb9c6da
本章介绍 **枚举***enumerations*),也被称作 *enums*。枚举允许你通过列举可能的 **成员***variants*)来定义一个类型。首先,我们会定义并使用一个枚举来展示它是如何连同数据一起编码信息的。接下来,我们会探索一个特别有用的枚举,叫做 `Option`,它代表一个值要么是某个值要么什么都不是。然后会讲到在 `match` 表达式中用模式匹配,针对不同的枚举值编写相应要执行的代码。最后会介绍 `if let`,另一个简洁方便处理代码中枚举的结构。 本章介绍 **枚举***enumerations*),也被称作 *enums*。枚举允许你通过列举可能的 **成员***variants*)来定义一个类型。首先,我们会定义并使用一个枚举来展示它是如何连同数据一起编码信息的。接下来,我们会探索一个特别有用的枚举,叫做 `Option`,它代表一个值要么是某个值要么什么都不是。然后会讲到在 `match` 表达式中用模式匹配,针对不同的枚举值编写相应要执行的代码。最后会介绍 `if let`,另一个简洁方便处理代码中枚举的结构。

@ -2,7 +2,7 @@
> [ch06-01-defining-an-enum.md](https://github.com/rust-lang/book/blob/main/src/ch06-01-defining-an-enum.md) > [ch06-01-defining-an-enum.md](https://github.com/rust-lang/book/blob/main/src/ch06-01-defining-an-enum.md)
> <br> > <br>
> commit c76f1b4d011fe59fc4f5e6f258070fc40d9921e4 > commit bb7e429ad6b59d9a0c37db7434976364cbb9c6da
结构体给予你将字段和数据聚合在一起的方法,像 `Rectangle` 结构体有 `width``height` 两个字段。而枚举给予你将一个值成为一个集合之一的方法。比如,我们想让 `Rectangle` 是一些形状的集合,包含 `Circle``Triangle` 。为了做到这个Rust 提供了枚举类型。 结构体给予你将字段和数据聚合在一起的方法,像 `Rectangle` 结构体有 `width``height` 两个字段。而枚举给予你将一个值成为一个集合之一的方法。比如,我们想让 `Rectangle` 是一些形状的集合,包含 `Circle``Triangle` 。为了做到这个Rust 提供了枚举类型。
@ -120,7 +120,7 @@ enum IpAddr {
这一部分会分析一个 `Option` 的案例,`Option` 是标准库定义的另一个枚举。`Option` 类型应用广泛因为它编码了一个非常普遍的场景,即一个值要么有值要么没值。 这一部分会分析一个 `Option` 的案例,`Option` 是标准库定义的另一个枚举。`Option` 类型应用广泛因为它编码了一个非常普遍的场景,即一个值要么有值要么没值。
例如,如果请求一个包含项的列表的第一个值,会得到一个值,如果请求一个空的列表,就什么也不会得到。从类型系统的角度来表达这个概念就意味着编译器需要检查是否处理了所有应该处理的情况,这样就可以避免在其他编程语言中非常常见的 bug。 例如,如果请求一个非空列表的第一项,会得到一个值,如果请求一个空的列表,就什么也不会得到。从类型系统的角度来表达这个概念就意味着编译器需要检查是否处理了所有应该处理的情况,这样就可以避免在其他编程语言中非常常见的 bug。
编程语言的设计经常要考虑包含哪些功能但考虑排除哪些功能也很重要。Rust 并没有很多其他语言中有的空值功能。**空值***Null* )是一个值,它代表没有值。在有空值的语言中,变量总是这两种状态之一:空值和非空值。 编程语言的设计经常要考虑包含哪些功能但考虑排除哪些功能也很重要。Rust 并没有很多其他语言中有的空值功能。**空值***Null* )是一个值,它代表没有值。在有空值的语言中,变量总是这两种状态之一:空值和非空值。
@ -176,13 +176,13 @@ enum Option<T> {
很好!事实上,错误信息意味着 Rust 不知道该如何将 `Option<i8>``i8` 相加,因为它们的类型不同。当在 Rust 中拥有一个像 `i8` 这样类型的值时,编译器确保它总是有一个有效的值。我们可以自信使用而无需做空值检查。只有当使用 `Option<i8>`(或者任何用到的类型)的时候需要担心可能没有值,而编译器会确保我们在使用值之前处理了为空的情况。 很好!事实上,错误信息意味着 Rust 不知道该如何将 `Option<i8>``i8` 相加,因为它们的类型不同。当在 Rust 中拥有一个像 `i8` 这样类型的值时,编译器确保它总是有一个有效的值。我们可以自信使用而无需做空值检查。只有当使用 `Option<i8>`(或者任何用到的类型)的时候需要担心可能没有值,而编译器会确保我们在使用值之前处理了为空的情况。
换句话说,在对 `Option<T>` 进行 `T`运算之前必须将其转换为 `T`。通常这能帮助我们捕获到空值最常见的问题之一:假设某值不为空但实际上为空的情况。 换句话说,在对 `Option<T>` 进行运算之前必须将其转换为 `T`。通常这能帮助我们捕获到空值最常见的问题之一:假设某值不为空但实际上为空的情况。
消除了错误地假设一个非空值的风险,会让你对代码更加有信心。为了拥有一个可能为空的值,你必须要显式的将其放入对应类型的 `Option<T>` 中。接着,当使用这个值时,必须明确的处理值为空的情况。只要一个值不是 `Option<T>` 类型,你就 **可以** 安全的认定它的值不为空。这是 Rust 的一个经过深思熟虑的设计决策,来限制空值的泛滥以增加 Rust 代码的安全性。 消除了错误地假设一个非空值的风险,会让你对代码更加有信心。为了拥有一个可能为空的值,你必须要显式的将其放入对应类型的 `Option<T>` 中。接着,当使用这个值时,必须明确的处理值为空的情况。只要一个值不是 `Option<T>` 类型,你就 **可以** 安全的认定它的值不为空。这是 Rust 的一个经过深思熟虑的设计决策,来限制空值的泛滥以增加 Rust 代码的安全性。
那么当有一个 `Option<T>` 的值时,如何从 `Some` 成员中取出 `T` 的值来使用它呢?`Option<T>` 枚举拥有大量用于各种情况的方法:你可以查看[它的文档][docs]<!-- ignore -->。熟悉 `Option<T>` 的方法将对你的 Rust 之旅非常有用。 那么当有一个 `Option<T>` 的值时,如何从 `Some` 成员中取出 `T` 的值来使用它呢?`Option<T>` 枚举拥有大量用于各种情况的方法:你可以查看[它的文档][docs]<!-- ignore -->。熟悉 `Option<T>` 的方法将对你的 Rust 之旅非常有用。
总的来说,为了使用 `Option<T>` 值,需要编写处理每个成员的代码。你想要一些代码只当拥有 `Some(T)` 值时运行,允许这些代码使用其中的 `T`。也希望一些代码在值为 `None` 时运行,这些代码并没有一个可用的 `T` 值。`match` 表达式就是这么一个处理枚举的控制流结构:它会根据枚举的成员运行不同的代码,这些代码可以使用匹配到的值中的数据。 总的来说,为了使用 `Option<T>` 值,需要编写处理每个成员的代码。你想要一些代码只当拥有 `Some(T)` 值时运行,允许这些代码使用其中的 `T`。也希望一些代码在值为 `None` 时运行,这些代码并没有一个可用的 `T` 值。`match` 表达式就是这么一个处理枚举的控制流结构:它会根据枚举的成员运行不同的代码,这些代码可以使用匹配到的值中的数据。
[IpAddr]: https://doc.rust-lang.org/std/net/enum.IpAddr.html [IpAddr]: https://doc.rust-lang.org/std/net/enum.IpAddr.html
[option]: https://doc.rust-lang.org/std/option/enum.Option.html [option]: https://doc.rust-lang.org/std/option/enum.Option.html

@ -2,9 +2,9 @@
> [ch06-02-match.md](https://github.com/rust-lang/book/blob/main/src/ch06-02-match.md) > [ch06-02-match.md](https://github.com/rust-lang/book/blob/main/src/ch06-02-match.md)
> <br> > <br>
> commit c76f1b4d011fe59fc4f5e6f258070fc40d9921e4 > commit 3962c0224b274e2358e0acf06443af64df115359
Rust 有一个叫做 `match` 的极为强大的控制流运算符,它允许我们将一个值与一系列的模式相比较,并根据相匹配的模式执行相应代码。模式可由字面值、变量、通配符和许多其他内容构成;第十八章会涉及到所有不同种类的模式以及它们的作用。`match` 的力量来源于模式的表现力以及编译器检查,它确保了所有可能的情况都得到处理。 Rust 有一个叫做 `match` 的极为强大的控制流运算符,它允许我们将一个值与一系列的模式相比较,并根据相匹配的模式执行相应代码。模式可由字面值、变量、通配符和许多其他内容构成;[第十八章][ch18-00-patterns]会涉及到所有不同种类的模式以及它们的作用。`match` 的力量来源于模式的表现力以及编译器检查,它确保了所有可能的情况都得到处理。
可以把 `match` 表达式想象成某种硬币分类器:硬币滑入有着不同大小孔洞的轨道,每一个硬币都会掉入符合它大小的孔洞。同样地,值也会通过 `match` 的每一个模式,并且在遇到第一个 “符合” 的模式时,值会进入相关联的代码块并在执行中被使用。 可以把 `match` 表达式想象成某种硬币分类器:硬币滑入有着不同大小孔洞的轨道,每一个硬币都会掉入符合它大小的孔洞。同样地,值也会通过 `match` 的每一个模式,并且在遇到第一个 “符合” 的模式时,值会进入相关联的代码块并在执行中被使用。
@ -16,7 +16,7 @@ Rust 有一个叫做 `match` 的极为强大的控制流运算符,它允许我
<span class="caption">示例 6-3一个枚举和一个以枚举成员作为模式的 `match` 表达式</span> <span class="caption">示例 6-3一个枚举和一个以枚举成员作为模式的 `match` 表达式</span>
拆开 `value_in_cents` 函数中的 `match` 来看。首先,我们列出 `match` 关键字后跟一个表达式,在这个例子中是 `coin` 的值。这看起来非常像 `if` 使用的表达式,不过这里有一个非常大的区别:对于 `if`,表达式必须返回一个布尔值,而这里它可以是任何类型的。例子中的 `coin` 的类型是示例 6-3 中定义的 `Coin` 枚举。 拆开 `value_in_cents` 函数中的 `match` 来看。首先,我们列出 `match` 关键字后跟一个表达式,在这个例子中是 `coin` 的值。这看起来非常像 `if` 使用的条件表达式,不过这里有一个非常大的区别:对于 `if`,表达式必须返回一个布尔值,而这里它可以是任何类型的。例子中的 `coin` 的类型是示例 6-3 中定义的 `Coin` 枚举。
接下来是 `match` 的分支。一个分支有两个部分:一个模式和一些代码。第一个分支的模式是值 `Coin::Penny` 而之后的 `=>` 运算符将模式和将要运行的代码分开。这里的代码就仅仅是值 `1`。每一个分支之间使用逗号分隔。 接下来是 `match` 的分支。一个分支有两个部分:一个模式和一些代码。第一个分支的模式是值 `Coin::Penny` 而之后的 `=>` 运算符将模式和将要运行的代码分开。这里的代码就仅仅是值 `1`。每一个分支之间使用逗号分隔。
@ -116,7 +116,7 @@ Rust 知道我们没有覆盖所有可能的情况甚至知道哪些模式被忘
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/src/main.rs:here}} {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/src/main.rs:here}}
``` ```
对于前两个分支,匹配模式是字面值 3 和 7最后一个分支则涵盖了所有其他可能的值模式是我们命名为 `other` 的一个变量。`other` 分支的代码通过将其传递给 `move_player` 函数来使用这个变量。 对于前两个分支,匹配模式是字面值 `3``7`,最后一个分支则涵盖了所有其他可能的值,模式是我们命名为 `other` 的一个变量。`other` 分支的代码通过将其传递给 `move_player` 函数来使用这个变量。
即使我们没有列出 `u8` 所有可能的值,这段代码依然能够编译,因为最后一个模式将匹配所有未被特殊列出的值。这种通配模式满足了 `match` 必须被穷尽的要求。请注意我们必须将通配分支放在最后因为模式是按顺序匹配的。如果我们在通配分支后添加其他分支Rust 将会警告我们,因为此后的分支永远不会被匹配到。 即使我们没有列出 `u8` 所有可能的值,这段代码依然能够编译,因为最后一个模式将匹配所有未被特殊列出的值。这种通配模式满足了 `match` 必须被穷尽的要求。请注意我们必须将通配分支放在最后因为模式是按顺序匹配的。如果我们在通配分支后添加其他分支Rust 将会警告我们,因为此后的分支永远不会被匹配到。

@ -2,7 +2,7 @@
> [ch06-03-if-let.md](https://github.com/rust-lang/book/blob/main/src/ch06-03-if-let.md) > [ch06-03-if-let.md](https://github.com/rust-lang/book/blob/main/src/ch06-03-if-let.md)
> <br> > <br>
> commit 40c98a5118d2ba93ce9fd39c313bcbce5597818d > commit bb7e429ad6b59d9a0c37db7434976364cbb9c6da
`if let` 语法让我们以一种不那么冗长的方式结合 `if``let`,来处理只匹配一个模式的值而忽略其他模式的情况。考虑示例 6-6 中的程序,它匹配一个 `config_max` 变量中的 `Option<u8>` 值并只希望当值为 `Some` 成员时执行代码: `if let` 语法让我们以一种不那么冗长的方式结合 `if``let`,来处理只匹配一个模式的值而忽略其他模式的情况。考虑示例 6-6 中的程序,它匹配一个 `config_max` 变量中的 `Option<u8>` 值并只希望当值为 `Some` 成员时执行代码:

Loading…
Cancel
Save