From 2706dfe0c7266f1ac66ce4c913a769a176b594b6 Mon Sep 17 00:00:00 2001 From: "rust-lang.xfoss.com" Date: Mon, 18 Dec 2023 13:53:02 +0800 Subject: [PATCH] Refining Ch06. --- projects/match_demo/Cargo.toml | 8 ++++++ projects/match_demo/src/main.rs | 26 +++++++++++++++++++ .../match_control_flow.md | 24 ++++++++++------- 3 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 projects/match_demo/Cargo.toml create mode 100644 projects/match_demo/src/main.rs diff --git a/projects/match_demo/Cargo.toml b/projects/match_demo/Cargo.toml new file mode 100644 index 0000000..473eeec --- /dev/null +++ b/projects/match_demo/Cargo.toml @@ -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] diff --git a/projects/match_demo/src/main.rs b/projects/match_demo/src/main.rs new file mode 100644 index 0000000..adc624b --- /dev/null +++ b/projects/match_demo/src/main.rs @@ -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)); +} diff --git a/src/enums_and_pattern_matching/match_control_flow.md b/src/enums_and_pattern_matching/match_control_flow.md index a9f6d50..866037d 100644 --- a/src/enums_and_pattern_matching/match_control_flow.md +++ b/src/enums_and_pattern_matching/match_control_flow.md @@ -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,