mirror of
https://github.com/KaiserY/trpl-zh-cn
synced 2025-05-23 18:18:13 +08:00
wip: 2024 edition
This commit is contained in:
parent
ac907219e7
commit
d26b9d4299
@ -1,7 +1,6 @@
|
||||
# 枚举和模式匹配
|
||||
|
||||
> [ch06-00-enums.md](https://github.com/rust-lang/book/blob/main/src/ch06-00-enums.md)
|
||||
> <br>
|
||||
> commit bb7e429ad6b59d9a0c37db7434976364cbb9c6da
|
||||
<!-- https://github.com/rust-lang/book/blob/main/src/ch06-00-enums.md -->
|
||||
<!-- commit 3a30e4c1fbe641afc066b3af9eb01dcdf5ed8b24 -->
|
||||
|
||||
本章介绍 **枚举**(*enumerations*),也被称作 *enums*。枚举允许你通过列举可能的 **成员**(*variants*)来定义一个类型。首先,我们会定义并使用一个枚举来展示它是如何连同数据一起编码信息的。接下来,我们会探索一个特别有用的枚举,叫做 `Option`,它代表一个值要么是某个值要么什么都不是。然后会讲到在 `match` 表达式中用模式匹配,针对不同的枚举值编写相应要执行的代码。最后会介绍 `if let`,另一个简洁方便处理代码中枚举的结构。
|
||||
本章介绍**枚举**(*enumerations*),也被称作 *enums*。枚举允许你通过列举可能的 **变体**(*variants*)来定义一个类型。首先,我们会定义并使用一个枚举来展示它是如何连同数据一起编码信息的。接下来,我们会探索一个特别有用的枚举,叫做 `Option`,它代表一个值要么是某个值要么什么都不是。然后会讲到在 `match` 表达式中用模式匹配,针对不同的枚举值编写相应要执行的代码。最后会介绍 `if let`,另一个简洁方便处理代码中枚举的结构。
|
||||
|
@ -1,16 +1,15 @@
|
||||
## 枚举的定义
|
||||
|
||||
> [ch06-01-defining-an-enum.md](https://github.com/rust-lang/book/blob/main/src/ch06-01-defining-an-enum.md)
|
||||
> <br>
|
||||
> commit bb7e429ad6b59d9a0c37db7434976364cbb9c6da
|
||||
<!-- https://github.com/rust-lang/book/blob/main/src/ch06-01-defining-an-enum.md -->
|
||||
<!-- commit 2a4c00c4d0c373ff9b416712b74ffb7ed56c77d4 -->
|
||||
|
||||
结构体给予你将字段和数据聚合在一起的方法,像 `Rectangle` 结构体有 `width` 和 `height` 两个字段。而枚举给予你一个途径去声明某个值是一个集合中的一员。比如,我们想让 `Rectangle` 是一些形状的集合,包含 `Circle` 和 `Triangle` 。为了做到这个,Rust 提供了枚举类型。
|
||||
结构体给予你将字段和数据聚合在一起的方法,像 `Rectangle` 结构体有 `width` 和 `height` 两个字段。而枚举给予你一个途径去声明某个值是一个集合中的一员。比如,我们想让 `Rectangle` 是一些形状的集合,包含 `Circle` 和 `Triangle` 。为此,Rust 允许我们将这些可能性编码为一个枚举类型。
|
||||
|
||||
让我们看看一个需要诉诸于代码的场景,来考虑为何此时使用枚举更为合适且实用。假设我们要处理 IP 地址。目前被广泛使用的两个主要 IP 标准:IPv4(version four)和 IPv6(version six)。这是我们的程序可能会遇到的所有可能的 IP 地址类型:所以可以 **枚举** 出所有可能的值,这也正是此枚举名字的由来。
|
||||
让我们看看一个需要诉诸于代码的场景,来考虑为何此时使用枚举更为合适且实用。假设我们要处理 IP 地址。目前被广泛使用的两个主要 IP 标准:IPv4(version four)和 IPv6(version six)。这是我们的程序可能会遇到的所有可能的 IP 地址类型:所以可以**枚举**出所有可能的值,这也正是枚举一词的由来。
|
||||
|
||||
任何一个 IP 地址要么是 IPv4 的要么是 IPv6 的,而且不能两者都是。IP 地址的这个特性使得枚举数据结构非常适合这个场景,因为枚举值只可能是其中一个成员。IPv4 和 IPv6 从根本上讲仍是 IP 地址,所以当代码在处理适用于任何类型的 IP 地址的场景时应该把它们当作相同的类型。
|
||||
任何一个 IP 地址要么是 IPv4 的要么是 IPv6 的,而且不能两者都是。IP 地址的这个特性使得枚举数据结构非常适合这个场景,因为枚举值只可能是其中一个变体。IPv4 和 IPv6 从根本上讲仍是 IP 地址,所以当代码在处理适用于任何类型的 IP 地址的场景时应该把它们当作相同的类型。
|
||||
|
||||
可以通过在代码中定义一个 `IpAddrKind` 枚举来表现这个概念并列出可能的 IP 地址类型,`V4` 和 `V6`。这被称为枚举的 **成员**(*variants*):
|
||||
可以通过在代码中定义一个 `IpAddrKind` 枚举来表现这个概念并列出可能的 IP 地址类型,`V4` 和 `V6`。这被称为枚举的**变体**(*variants*):
|
||||
|
||||
```rust
|
||||
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/src/main.rs:def}}
|
||||
@ -20,49 +19,49 @@
|
||||
|
||||
### 枚举值
|
||||
|
||||
可以像这样创建 `IpAddrKind` 两个不同成员的实例:
|
||||
可以像这样创建 `IpAddrKind` 两个不同变体的实例:
|
||||
|
||||
```rust
|
||||
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/src/main.rs:instance}}
|
||||
```
|
||||
|
||||
注意枚举的成员位于其标识符的命名空间中,并使用两个冒号分开。这么设计的益处是现在 `IpAddrKind::V4` 和 `IpAddrKind::V6` 都是 `IpAddrKind` 类型的。例如,接着可以定义一个函数来接收任何 `IpAddrKind`类型的参数:
|
||||
注意枚举的变体位于其标识符的命名空间中,并使用两个冒号分开。这么设计的益处是现在 `IpAddrKind::V4` 和 `IpAddrKind::V6` 都是 `IpAddrKind` 类型的。例如,接着可以定义一个函数来接收任何 `IpAddrKind`类型的参数:
|
||||
|
||||
```rust
|
||||
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/src/main.rs:fn}}
|
||||
```
|
||||
|
||||
现在可以使用任一成员来调用这个函数:
|
||||
现在可以使用任一变体来调用这个函数:
|
||||
|
||||
```rust
|
||||
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/src/main.rs:fn_call}}
|
||||
```
|
||||
|
||||
使用枚举甚至还有更多优势。进一步考虑一下我们的 IP 地址类型,目前没有一个存储实际 IP 地址 **数据** 的方法;只知道它是什么 **类型** 的。考虑到已经在第五章学习过结构体了,你可能会像示例 6-1 那样处理这个问题:
|
||||
使用枚举甚至还有更多优势。进一步考虑一下我们的 IP 地址类型,目前没有一个存储实际 IP 地址**数据**的方法;只知道它是什么**类型**的。考虑到已经在第五章学习过结构体了,你可能会像示例 6-1 那样尝试用结构体来解决这个问题:
|
||||
|
||||
```rust
|
||||
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-01/src/main.rs:here}}
|
||||
```
|
||||
|
||||
<span class="caption">示例 6-1:将 IP 地址的数据和 `IpAddrKind` 成员存储在一个 `struct` 中</span>
|
||||
<span class="caption">示例 6-1:将 IP 地址的数据和 `IpAddrKind` 变体存储在一个 `struct` 中</span>
|
||||
|
||||
这里我们定义了一个有两个字段的结构体 `IpAddr`:`IpAddrKind`(之前定义的枚举)类型的 `kind` 字段和 `String` 类型 `address` 字段。我们有这个结构体的两个实例。第一个,`home`,它的 `kind` 的值是 `IpAddrKind::V4` 与之相关联的地址数据是 `127.0.0.1`。第二个实例,`loopback`,`kind` 的值是 `IpAddrKind` 的另一个成员,`V6`,关联的地址是 `::1`。我们使用了一个结构体来将 `kind` 和 `address` 打包在一起,现在枚举成员就与值相关联了。
|
||||
这里我们定义了一个有两个字段的结构体 `IpAddr`:`IpAddrKind`(之前定义的枚举)类型的 `kind` 字段和 `String` 类型 `address` 字段。我们有这个结构体的两个实例。第一个,`home`,它的 `kind` 的值是 `IpAddrKind::V4` 与之相关联的地址数据是 `127.0.0.1`。第二个实例,`loopback`,`kind` 的值是 `IpAddrKind` 的另一个变体,`V6`,关联的地址是 `::1`。我们使用了一个结构体来将 `kind` 和 `address` 打包在一起,现在枚举变体就与值相关联了。
|
||||
|
||||
我们可以使用一种更简洁的方式来表达相同的概念,仅仅使用枚举并将数据直接放进每一个枚举成员而不是将枚举作为结构体的一部分。`IpAddr` 枚举的新定义表明了 `V4` 和 `V6` 成员都关联了 `String` 值:
|
||||
我们可以使用一种更简洁的方式来表达相同的概念,仅仅使用枚举并将数据直接放进每一个枚举变体而不是将枚举作为结构体的一部分。`IpAddr` 枚举的新定义表明了 `V4` 和 `V6` 变体都关联了 `String` 值:
|
||||
|
||||
```rust
|
||||
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/src/main.rs:here}}
|
||||
```
|
||||
|
||||
我们直接将数据附加到枚举的每个成员上,这样就不需要一个额外的结构体了。这里也很容易看出枚举工作的另一个细节:每一个我们定义的枚举成员的名字也变成了一个构建枚举的实例的函数。也就是说,`IpAddr::V4()` 是一个获取 `String` 参数并返回 `IpAddr` 类型实例的函数调用。作为定义枚举的结果,这些构造函数会自动被定义。
|
||||
我们直接将数据附加到枚举的每个变体上,这样就不需要一个额外的结构体了。这里也很容易看出枚举工作的另一个细节:每一个我们定义的枚举变体的名字也变成了一个构建枚举的实例的函数。也就是说,`IpAddr::V4()` 是一个获取 `String` 参数并返回 `IpAddr` 类型实例的函数调用。作为定义枚举的结果,这些构造函数会自动被定义。
|
||||
|
||||
用枚举替代结构体还有另一个优势:每个成员可以处理不同类型和数量的数据。IPv4 版本的 IP 地址总是含有四个值在 0 和 255 之间的数字部分。如果我们想要将 `V4` 地址存储为四个 `u8` 值而 `V6` 地址仍然表现为一个 `String`,这就不能使用结构体了。枚举则可以轻易的处理这个情况:
|
||||
用枚举替代结构体还有另一个优势:每个变体可以处理不同类型和数量的数据。IPv4 版本的 IP 地址总是含有四个值在 0 和 255 之间的数字部分。如果我们想要将 `V4` 地址存储为四个 `u8` 值而 `V6` 地址仍然表现为一个 `String`,这就不能使用结构体了。枚举则可以轻易的处理这个情况:
|
||||
|
||||
```rust
|
||||
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/src/main.rs:here}}
|
||||
```
|
||||
|
||||
这些代码展示了使用枚举来存储两种不同 IP 地址的几种可能的选择。然而,事实证明存储和编码 IP 地址实在是太常见了[以致标准库提供了一个开箱即用的定义!][IpAddr]<!-- ignore -->让我们看看标准库是如何定义 `IpAddr` 的:它正有着跟我们定义和使用的一样的枚举和成员,不过它将成员中的地址数据嵌入到了两个不同形式的结构体中,它们对不同的成员的定义是不同的:
|
||||
这些代码展示了使用枚举来存储两种不同 IP 地址的几种可能的选择。然而,事实证明存储和编码 IP 地址实在是太常见了[以致标准库提供了一个开箱即用的定义!][IpAddr]<!-- ignore -->让我们看看标准库是如何定义 `IpAddr` 的:它正有着跟我们定义和使用的一样的枚举和变体,不过它将变体中的地址数据嵌入到了两个不同形式的结构体中,它们对不同的变体的定义是不同的:
|
||||
|
||||
```rust
|
||||
struct Ipv4Addr {
|
||||
@ -79,26 +78,26 @@ enum IpAddr {
|
||||
}
|
||||
```
|
||||
|
||||
这些代码展示了可以将任意类型的数据放入枚举成员中:例如字符串、数字类型或者结构体。甚至可以包含另一个枚举!另外,标准库中的类型通常并不比你设想出来的要复杂多少。
|
||||
这些代码展示了可以将任意类型的数据放入枚举变体中:例如字符串、数字类型或者结构体。甚至可以包含另一个枚举!另外,标准库中的类型通常并不比你设想出来的要复杂多少。
|
||||
|
||||
注意虽然标准库中包含一个 `IpAddr` 的定义,仍然可以创建和使用我们自己的定义而不会有冲突,因为我们并没有将标准库中的定义引入作用域。第七章会讲到如何导入类型。
|
||||
|
||||
来看看示例 6-2 中的另一个枚举的例子:它的成员中内嵌了多种多样的类型:
|
||||
来看看示例 6-2 中的另一个枚举的例子:它的变体中内嵌了多种多样的类型:
|
||||
|
||||
```rust
|
||||
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-02/src/main.rs:here}}
|
||||
```
|
||||
|
||||
<span class="caption">示例 6-2:一个 `Message` 枚举,其每个成员都存储了不同数量和类型的值</span>
|
||||
<span class="caption">示例 6-2:一个 `Message` 枚举,其每个变体都存储了不同数量和类型的值</span>
|
||||
|
||||
这个枚举有四个含有不同类型的成员:
|
||||
这个枚举有四个含有不同类型的变体:
|
||||
|
||||
* `Quit` 没有关联任何数据。
|
||||
* `Move` 类似结构体包含命名字段。
|
||||
* `Write` 包含单独一个 `String`。
|
||||
* `ChangeColor` 包含三个 `i32`。
|
||||
|
||||
定义一个如示例 6-2 中所示那样的有关联值的枚举的方式和定义多个不同类型的结构体的方式很相像,除了枚举不使用 `struct` 关键字以及其所有成员都被组合在一起位于 `Message` 类型下。如下这些结构体可以包含与之前枚举成员中相同的数据:
|
||||
定义一个如示例 6-2 中所示那样的有关联值的枚举的方式和定义多个不同类型的结构体的方式很相像,除了枚举不使用 `struct` 关键字以及其所有变体都被组合在一起位于 `Message` 类型下。如下这些结构体可以包含与之前枚举变体中相同的数据:
|
||||
|
||||
```rust
|
||||
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/src/main.rs:here}}
|
||||
@ -116,7 +115,7 @@ enum IpAddr {
|
||||
|
||||
让我们看看标准库中的另一个非常常见且实用的枚举:`Option`。
|
||||
|
||||
### `Option` 枚举和其相对于空值的优势
|
||||
### `Option` 枚举及其相对于空值的优势
|
||||
|
||||
这一部分会分析一个 `Option` 的案例,`Option` 是标准库定义的另一个枚举。`Option` 类型应用广泛因为它编码了一个非常普遍的场景,即一个值要么有值要么没值。
|
||||
|
||||
@ -135,7 +134,7 @@ Tony Hoare,null 的发明者,在他 2009 年的演讲 “Null References: Th
|
||||
> crashes, which have probably caused a billion dollars of pain and damage in
|
||||
> the last forty years.
|
||||
>
|
||||
> 我称之为我十亿美元的错误。当时,我在为一个面向对象语言设计第一个综合性的面向引用的类型系统。我的目标是通过编译器的自动检查来保证所有引用的使用都应该是绝对安全的。不过我未能抵抗住引入一个空引用的诱惑,仅仅是因为它是这么的容易实现。这引发了无数错误、漏洞和系统崩溃,在之后的四十多年中造成了数十亿美元的苦痛和伤害。
|
||||
> 我称之为我十亿美元的错误。当时,我在为一个面向对象语言设计第一个综合性的面向引用的类型系统。我的目标是通过编译器的自动检查来保证所有引用的使用都应该是绝对安全的。不过我未能抵抗住引入一个空引用的诱惑,仅仅是因为它是这么的容易实现。这引发了无数错误、漏洞和系统崩溃,在过去四十年里可能造成了价值十亿美元的痛苦和损失。
|
||||
|
||||
空值的问题在于当你尝试像一个非空值那样使用一个空值,会出现某种形式的错误。因为空和非空的属性无处不在,非常容易出现这类错误。
|
||||
|
||||
@ -150,15 +149,15 @@ enum Option<T> {
|
||||
}
|
||||
```
|
||||
|
||||
`Option<T>` 枚举是如此有用以至于它甚至被包含在了 prelude 之中,你不需要将其显式引入作用域。另外,它的成员也是如此,可以不需要 `Option::` 前缀来直接使用 `Some` 和 `None`。即便如此 `Option<T>` 也仍是常规的枚举,`Some(T)` 和 `None` 仍是 `Option<T>` 的成员。
|
||||
`Option<T>` 枚举是如此有用以至于它甚至被包含在了 prelude 之中,无需将其显式引入作用域。另外,它的变体也是如此:可以不需要 `Option::` 前缀来直接使用 `Some` 和 `None`。即便如此 `Option<T>` 也仍是常规的枚举,`Some(T)` 和 `None` 仍是 `Option<T>` 的变体。
|
||||
|
||||
`<T>` 语法是一个我们还未讲到的 Rust 功能。它是一个泛型类型参数,第十章会更详细的讲解泛型。目前,所有你需要知道的就是 `<T>` 意味着 `Option` 枚举的 `Some` 成员可以包含任意类型的数据,同时每一个用于 `T` 位置的具体类型使得 `Option<T>` 整体作为不同的类型。这里是一些包含数字类型和字符串类型 `Option` 值的例子:
|
||||
`<T>` 语法是一个我们还未讲到的 Rust 功能。它是一个泛型类型参数,第十章会更详细的讲解泛型。目前,所有你需要知道的就是 `<T>` 意味着 `Option` 枚举的 `Some` 变体可以包含任意类型的数据,同时每一个用于 `T` 位置的具体类型使得 `Option<T>` 整体作为不同的类型。这里是一些包含数字类型和字符串类型 `Option` 值的例子:
|
||||
|
||||
```rust
|
||||
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs:here}}
|
||||
```
|
||||
|
||||
`some_number` 的类型是 `Option<i32>`。`some_char` 的类型是 `Option<char>`,是不同于`some_number`的类型。因为我们在 `Some` 成员中指定了值,Rust 可以推断其类型。对于 `absent_number`,Rust 需要我们指定 `Option` 整体的类型,因为编译器只通过 `None` 值无法推断出 `Some` 成员保存的值的类型。这里我们告诉 Rust 希望 `absent_number` 是 `Option<i32>` 类型的。
|
||||
`some_number` 的类型是 `Option<i32>`。`some_char` 的类型是 `Option<char>`,是不同于 `some_number` 的类型。因为我们在 `Some` 变体中指定了值,Rust 可以推断其类型。对于 `absent_number`,Rust 需要我们指定 `Option` 整体的类型,因为编译器只通过 `None` 值无法推断出 `Some` 变体保存的值的类型。这里我们告诉 Rust 希望 `absent_number` 是 `Option<i32>` 类型的。
|
||||
|
||||
当有一个 `Some` 值时,我们就知道存在一个值,而这个值保存在 `Some` 中。当有个 `None` 值时,在某种意义上,它跟空值具有相同的意义:并没有一个有效的值。那么,`Option<T>` 为什么就比空值要好呢?
|
||||
|
||||
@ -174,15 +173,15 @@ enum Option<T> {
|
||||
{{#include ../listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/output.txt}}
|
||||
```
|
||||
|
||||
很好!事实上,错误信息意味着 Rust 不知道该如何将 `Option<i8>` 与 `i8` 相加,因为它们的类型不同。当在 Rust 中拥有一个像 `i8` 这样类型的值时,编译器确保它总是有一个有效的值。我们可以自信使用而无需做空值检查。只有当使用 `Option<i8>`(或者任何用到的类型)的时候需要担心可能没有值,而编译器会确保我们在使用值之前处理了为空的情况。
|
||||
很好!事实上,错误信息意味着 Rust 不知道该如何将 `Option<i8>` 与 `i8` 相加,因为它们的类型不同。当在 Rust 中拥有一个像 `i8` 这样类型的值时,编译器确保它总是有一个有效的值。我们可以自信地使用而无需做空值检查。只有当使用 `Option<i8>`(或者任何用到的类型)的时候需要担心可能没有值,而编译器会确保我们在使用值之前处理了为空的情况。
|
||||
|
||||
换句话说,在对 `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
|
||||
[option]: https://doc.rust-lang.org/std/option/enum.Option.html
|
||||
|
@ -1,8 +1,7 @@
|
||||
## `match` 控制流结构
|
||||
|
||||
> [ch06-02-match.md](https://github.com/rust-lang/book/blob/main/src/ch06-02-match.md)
|
||||
> <br>
|
||||
> commit 3962c0224b274e2358e0acf06443af64df115359
|
||||
<!-- https://github.com/rust-lang/book/blob/main/src/ch06-02-match.md -->
|
||||
<!-- commit 5d22a358fb2380aa3f270d7b6269b67b8e44849e -->
|
||||
|
||||
Rust 有一个叫做 `match` 的极为强大的控制流运算符,它允许我们将一个值与一系列的模式相比较,并根据相匹配的模式执行相应代码。模式可由字面值、变量、通配符和许多其他内容构成;[第十九章][ch19-00-patterns]会涉及到所有不同种类的模式以及它们的作用。`match` 的力量来源于模式的表现力以及编译器检查,它确保了所有可能的情况都得到处理。
|
||||
|
||||
|
@ -282,7 +282,7 @@ Miri 并不能捕获编写不安全代码时可能出现的所有错误。Miri
|
||||
[dangling-references]: ch04-02-references-and-borrowing.html#悬垂引用dangling-references
|
||||
[ABI]: https://doc.rust-lang.org/reference/items/external-blocks.html#abi
|
||||
[differences-between-variables-and-constants]: ch03-01-variables-and-mutability.html#常量
|
||||
[extensible-concurrency-with-the-sync-and-send-traits]: ch16-04-extensible-concurrency-sync-and-send.html#使用-sync-和-send-trait-的可扩展并发
|
||||
[extensible-concurrency-with-the-sync-and-send-traits]: ch16-04-extensible-concurrency-sync-and-send.html#使用-send-和-sync-trait-的可扩展并发
|
||||
[the-slice-type]: ch04-03-slices.html#slice-类型
|
||||
[unions]: https://doc.rust-lang.org/reference/items/unions.html
|
||||
[miri]: https://github.com/rust-lang/miri
|
||||
|
Loading…
Reference in New Issue
Block a user