mirror of
https://github.com/gnu4cn/rust-lang-zh_CN.git
synced 2024-12-25 20:30:34 +08:00
Refining Ch06.
This commit is contained in:
parent
55746ebe6a
commit
2706dfe0c7
8
projects/match_demo/Cargo.toml
Normal file
8
projects/match_demo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "match_demo"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
26
projects/match_demo/src/main.rs
Normal file
26
projects/match_demo/src/main.rs
Normal file
@ -0,0 +1,26 @@
|
||||
enum Coin {
|
||||
Penny,
|
||||
Nickel,
|
||||
Dime,
|
||||
Quarter,
|
||||
}
|
||||
|
||||
fn value_in_cents(coin: Coin) -> u8 {
|
||||
match coin {
|
||||
Coin::Penny => {
|
||||
println! ("Lucky penny!");
|
||||
1
|
||||
}
|
||||
Coin::Nickel => 5,
|
||||
Coin::Dime => 10,
|
||||
Coin::Quarter => 25,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let penny = Coin::Penny;
|
||||
let dime = Coin::Dime;
|
||||
|
||||
println! ("{}", value_in_cents(penny));
|
||||
println! ("{}", value_in_cents(dime));
|
||||
}
|
@ -1,8 +1,12 @@
|
||||
# `match` 控制流结构
|
||||
|
||||
Rust 有值一种即为强大的、名为 `match` 的控制流结构,此控制流结构实现了将某个值与一系列模式的比较,并根据所匹配模式而执行相应的代码。模式可由字面值、变量名字、通配符及其他事物等构成;第 18 章会涵盖到全部不同种类的模式及其所完成的事情。`match` 的强大来自模式的表达能力,以及编译器对全部可能情形都被处理进行确认这一事实。
|
||||
**The `match` Control Flow Construct**
|
||||
|
||||
|
||||
Rust 有一种名为 `match` 的非常强大的控制流结构,他允许咱们,将某个值与一系列模式比较,然后根据匹配的模式执行代码。模式可以由字面值、变量名、通配符及许多其他内容组成;[第 18 章](../Ch18_Patterns_and_Matching.md) 将介绍所有不同种类的模式及其作用。`match` 的威力,来自于模式的表现力,以及编译器确认所有可能情况都已得到处理,这一事实。
|
||||
|
||||
请把 `match` 表达式,设想成一台硬币分拣机:硬币沿着带有大小不一孔的轨道滑下,每枚硬币都会从他遇到的第一个适合的孔中落下。同样,值会遍历 `match` 表达式中的每个模式,在值 “适合” 的第一个模式处,值会落入关联的代码块,以便在执行过程中使用。
|
||||
|
||||
请将 `match` 表达式设想为一种类似硬币分选机这样的东西:硬币随一个滑道滚下,沿着这滑道有不同尺寸的洞,那么每个硬币都会在他碰到的第一个大小合适的洞那里掉落。同样道理,所有值都会历经 `match` 表达式中的各个模式,而在值 “适合” 的第一个模式处,那个值就会掉入到相关代码块,而在执行过程中被使用到。既然讲到了硬币,那么下面就来将其用作一个用到 `match` 表达式的示例!这里可以编写一个接收未知硬币,并以与点数机类似方式,判断出该硬币是何硬币而返回以分计的值来的函数,如下面清单 6-3 中所示。
|
||||
|
||||
```rust
|
||||
enum Coin {
|
||||
@ -22,23 +26,25 @@ fn value_in_cents(coin: Coin) -> u8 {
|
||||
}
|
||||
```
|
||||
|
||||
*清单 6-3:一个枚举与一个将该枚举的那些变种作为其模式的 `match` 表达式*
|
||||
*清单 6-3:一个枚举和一个以该枚举的变种为模式的 `match` 表达式*
|
||||
|
||||
这里就来把在 `value_in_cents` 函数中的那个 `match` 拆开讲讲。首先,这里是将 `match` 关键字后面跟上一个表达式,这里也就是 `coin` 后,列出来的。这就跟与 `if` 关键字一起使用的表达式极为相似,然而有个大的区别:在 `if` 之下,表达式需要返回一个布尔值,而在这里,该表达式可返回任意类型。此示例中 `coin` 的类型,即是这里在第一行上所定义的枚举 `Coin`。
|
||||
|
||||
接下来就是这个 `match` 表达式的各个支臂了。一个支臂有着两个部分:一个模式与一些代码。这里的第一个支臂,有着值为 `Coin::Penny` 的模式,同时其中的箭头运算符 `=>` 将模式与要运行的代码分隔开来。此情形下的代码,就只是值 `1`。各个支臂则是以逗号接着分开的。
|
||||
我们来分析一下 `value_in_cents` 函数中的那个 `match` 表达式。首先,我们列出了后跟一个表达式(本例中即为 `coin` 这个值)的 `match` 关键字。这似乎与 `if` 中使用的条件表达式非常相似,但有个很大的区别:在 `if` 中,条件需要求值为某个布尔值,但在这里,则可以是任何类型。本例中的 `coin` 类型,就是我们在第一行定义的那个 `Coin` 枚举。
|
||||
|
||||
在这个 `match` 表达式执行时,他就会依序将结果值与各个支臂的模式加以比较。在某个模式与该值匹配时,与那个模式关联的代码就被执行。而在那个模式不与该值匹配时,执行就会继续到下一支臂,就跟硬币分选机是一样的。这里需要多少支臂,就可以有多少支臂:在清单 6-3 中的 `match` 表达式,就有四个支臂。
|
||||
接下来是那些 `match` 的支臂。支臂由两部分组成:模式与一些代码。这里的第一个支臂有着值 `Coin::Penny` 的模式,然后是分隔模式和要运行代码的 `=>` 操作符。此情形下的代码只是值 `1`。每个支臂之间,用逗号隔开。
|
||||
|
||||
与各个支臂关联的代码,是个表达式,而在匹配支臂中的表达式返回值,就是整个 `match` 表达式所返回的值。
|
||||
当 `match` 表达式执行时,他会将 `match` 关键字后表达式的结果值,按顺序地与每个支臂的模式进行比较。如果某个模式与该值匹配,则执行与该模式相关的代码。如果该模式与该值不匹配,则继续执行下一支臂,就像硬币分拣机一样。我们可以根据需要,有着任意多个支臂:在清单 6-3 中,我们的 `match` 表达式,就有四个支臂。
|
||||
|
||||
与每个支臂相关的代码,是个表达式,匹配的支臂中表达式的结果值,就是整个 `match` 表达式返回的值。
|
||||
|
||||
如果匹配支臂代码很短,就像清单 6-3 中,每个匹配臂只返回一个值那样,我们通常不会使用花括号。如果要在某个匹配支臂中运行多行代码,则必须使用花括号,且匹配支臂后面的那个逗号,此时便成为可选的了。例如,下面的代码会在每次以 `Coin::Penny` 调用该函数时,打印出 "Lucky penny!",但仍会返回那个代码块的最后值 `1`:
|
||||
|
||||
正如清单 6-3 中,每个支臂只是返回一个值那样,在 `match` 表达式支臂代码,为简短代码时,就通常不会使用花括号。而在要于某个 `match` 支臂中运行多行代码时,就必须使用花括号。比如下面的代码,在该方法每次以 `Coin::Penny` 被调用时,都会打印出 “幸运便士!”,不过仍会返回该代码块的最后值,`1`:
|
||||
|
||||
```rust
|
||||
fn value_in_cents(coin: Coin) -> u8 {
|
||||
match coin {
|
||||
Coin::Penny => {
|
||||
println! ("幸运便士!");
|
||||
println! ("Lucky penny!");
|
||||
1
|
||||
},
|
||||
Coin::Nickel => 5,
|
||||
|
Loading…
Reference in New Issue
Block a user