diff --git a/docs/ch01-00-introduction.html b/docs/ch01-00-introduction.html index ecf70c4..7a847ec 100644 --- a/docs/ch01-00-introduction.html +++ b/docs/ch01-00-introduction.html @@ -47,7 +47,7 @@
diff --git a/docs/ch01-01-installation.html b/docs/ch01-01-installation.html index 9ed7dac..30e9628 100644 --- a/docs/ch01-01-installation.html +++ b/docs/ch01-01-installation.html @@ -47,7 +47,7 @@
diff --git a/docs/ch01-02-hello-world.html b/docs/ch01-02-hello-world.html index e4804d8..127271b 100644 --- a/docs/ch01-02-hello-world.html +++ b/docs/ch01-02-hello-world.html @@ -47,7 +47,7 @@
diff --git a/docs/ch02-00-guessing-game-tutorial.html b/docs/ch02-00-guessing-game-tutorial.html index e4e28ee..20683f3 100644 --- a/docs/ch02-00-guessing-game-tutorial.html +++ b/docs/ch02-00-guessing-game-tutorial.html @@ -47,7 +47,7 @@
diff --git a/docs/ch03-00-common-programming-concepts.html b/docs/ch03-00-common-programming-concepts.html index 1e31bae..47b3254 100644 --- a/docs/ch03-00-common-programming-concepts.html +++ b/docs/ch03-00-common-programming-concepts.html @@ -47,7 +47,7 @@
diff --git a/docs/ch03-01-variables-and-mutability.html b/docs/ch03-01-variables-and-mutability.html index dfe0405..729fc41 100644 --- a/docs/ch03-01-variables-and-mutability.html +++ b/docs/ch03-01-variables-and-mutability.html @@ -47,7 +47,7 @@
diff --git a/docs/ch03-02-data-types.html b/docs/ch03-02-data-types.html index 6a5ddbc..29e7206 100644 --- a/docs/ch03-02-data-types.html +++ b/docs/ch03-02-data-types.html @@ -47,7 +47,7 @@
diff --git a/docs/ch03-03-how-functions-work.html b/docs/ch03-03-how-functions-work.html index 7fd4bad..dcae96b 100644 --- a/docs/ch03-03-how-functions-work.html +++ b/docs/ch03-03-how-functions-work.html @@ -47,7 +47,7 @@
diff --git a/docs/ch03-04-comments.html b/docs/ch03-04-comments.html index 903450b..4699130 100644 --- a/docs/ch03-04-comments.html +++ b/docs/ch03-04-comments.html @@ -47,7 +47,7 @@
diff --git a/docs/ch03-05-control-flow.html b/docs/ch03-05-control-flow.html index b457c65..65745c0 100644 --- a/docs/ch03-05-control-flow.html +++ b/docs/ch03-05-control-flow.html @@ -47,7 +47,7 @@
diff --git a/docs/ch04-00-understanding-ownership.html b/docs/ch04-00-understanding-ownership.html index 71a37a9..708a7bd 100644 --- a/docs/ch04-00-understanding-ownership.html +++ b/docs/ch04-00-understanding-ownership.html @@ -47,7 +47,7 @@
diff --git a/docs/ch04-01-what-is-ownership.html b/docs/ch04-01-what-is-ownership.html index 278484f..afcaa5b 100644 --- a/docs/ch04-01-what-is-ownership.html +++ b/docs/ch04-01-what-is-ownership.html @@ -47,7 +47,7 @@
diff --git a/docs/ch04-02-references-and-borrowing.html b/docs/ch04-02-references-and-borrowing.html index de395fd..f09cf7f 100644 --- a/docs/ch04-02-references-and-borrowing.html +++ b/docs/ch04-02-references-and-borrowing.html @@ -47,7 +47,7 @@
diff --git a/docs/ch04-03-slices.html b/docs/ch04-03-slices.html index f0656f2..6746114 100644 --- a/docs/ch04-03-slices.html +++ b/docs/ch04-03-slices.html @@ -47,7 +47,7 @@
diff --git a/docs/ch05-00-structs.html b/docs/ch05-00-structs.html index 0831376..73501ce 100644 --- a/docs/ch05-00-structs.html +++ b/docs/ch05-00-structs.html @@ -47,7 +47,7 @@
diff --git a/docs/ch05-01-method-syntax.html b/docs/ch05-01-method-syntax.html index e2fb372..5103b14 100644 --- a/docs/ch05-01-method-syntax.html +++ b/docs/ch05-01-method-syntax.html @@ -47,7 +47,7 @@
diff --git a/docs/ch06-00-enums.html b/docs/ch06-00-enums.html index 42d053b..53f2933 100644 --- a/docs/ch06-00-enums.html +++ b/docs/ch06-00-enums.html @@ -47,7 +47,7 @@
diff --git a/docs/ch06-01-defining-an-enum.html b/docs/ch06-01-defining-an-enum.html index be9c99b..d87bd65 100644 --- a/docs/ch06-01-defining-an-enum.html +++ b/docs/ch06-01-defining-an-enum.html @@ -47,7 +47,7 @@
diff --git a/docs/ch06-02-match.html b/docs/ch06-02-match.html index bda3870..79ba6cc 100644 --- a/docs/ch06-02-match.html +++ b/docs/ch06-02-match.html @@ -47,7 +47,7 @@
diff --git a/docs/ch06-03-if-let.html b/docs/ch06-03-if-let.html index e241604..c692905 100644 --- a/docs/ch06-03-if-let.html +++ b/docs/ch06-03-if-let.html @@ -47,7 +47,7 @@
diff --git a/docs/ch07-00-modules.html b/docs/ch07-00-modules.html index 502421c..3e84ee3 100644 --- a/docs/ch07-00-modules.html +++ b/docs/ch07-00-modules.html @@ -47,7 +47,7 @@
diff --git a/docs/ch07-01-mod-and-the-filesystem.html b/docs/ch07-01-mod-and-the-filesystem.html index d36186b..c043bdf 100644 --- a/docs/ch07-01-mod-and-the-filesystem.html +++ b/docs/ch07-01-mod-and-the-filesystem.html @@ -47,7 +47,7 @@
diff --git a/docs/ch07-02-controlling-visibility-with-pub.html b/docs/ch07-02-controlling-visibility-with-pub.html index 3546f27..4e90991 100644 --- a/docs/ch07-02-controlling-visibility-with-pub.html +++ b/docs/ch07-02-controlling-visibility-with-pub.html @@ -47,7 +47,7 @@
diff --git a/docs/ch07-03-importing-names-with-use.html b/docs/ch07-03-importing-names-with-use.html index 29ace93..3be8dda 100644 --- a/docs/ch07-03-importing-names-with-use.html +++ b/docs/ch07-03-importing-names-with-use.html @@ -47,7 +47,7 @@
diff --git a/docs/ch08-00-common-collections.html b/docs/ch08-00-common-collections.html index 4d404b2..f3c3fdc 100644 --- a/docs/ch08-00-common-collections.html +++ b/docs/ch08-00-common-collections.html @@ -47,7 +47,7 @@
diff --git a/docs/ch08-01-vectors.html b/docs/ch08-01-vectors.html index eeab2e7..2aa7642 100644 --- a/docs/ch08-01-vectors.html +++ b/docs/ch08-01-vectors.html @@ -47,7 +47,7 @@
diff --git a/docs/ch08-02-strings.html b/docs/ch08-02-strings.html index b3043a2..f0daecc 100644 --- a/docs/ch08-02-strings.html +++ b/docs/ch08-02-strings.html @@ -47,7 +47,7 @@
diff --git a/docs/ch08-03-hash-maps.html b/docs/ch08-03-hash-maps.html index b4697c1..5a65066 100644 --- a/docs/ch08-03-hash-maps.html +++ b/docs/ch08-03-hash-maps.html @@ -47,7 +47,7 @@
diff --git a/docs/ch09-00-error-handling.html b/docs/ch09-00-error-handling.html index b81c7bc..6fa01ab 100644 --- a/docs/ch09-00-error-handling.html +++ b/docs/ch09-00-error-handling.html @@ -47,7 +47,7 @@
diff --git a/docs/ch09-01-unrecoverable-errors-with-panic.html b/docs/ch09-01-unrecoverable-errors-with-panic.html index bce2e2c..994f39c 100644 --- a/docs/ch09-01-unrecoverable-errors-with-panic.html +++ b/docs/ch09-01-unrecoverable-errors-with-panic.html @@ -47,7 +47,7 @@
diff --git a/docs/ch09-02-recoverable-errors-with-result.html b/docs/ch09-02-recoverable-errors-with-result.html index aa3c20f..e980678 100644 --- a/docs/ch09-02-recoverable-errors-with-result.html +++ b/docs/ch09-02-recoverable-errors-with-result.html @@ -47,7 +47,7 @@
diff --git a/docs/ch09-03-to-panic-or-not-to-panic.html b/docs/ch09-03-to-panic-or-not-to-panic.html index d6d0183..4dd566c 100644 --- a/docs/ch09-03-to-panic-or-not-to-panic.html +++ b/docs/ch09-03-to-panic-or-not-to-panic.html @@ -47,7 +47,7 @@
diff --git a/docs/ch10-00-generics.html b/docs/ch10-00-generics.html index 655f00c..e5bdfa2 100644 --- a/docs/ch10-00-generics.html +++ b/docs/ch10-00-generics.html @@ -47,7 +47,7 @@
diff --git a/docs/ch10-01-syntax.html b/docs/ch10-01-syntax.html index 9de05ac..0dde4f1 100644 --- a/docs/ch10-01-syntax.html +++ b/docs/ch10-01-syntax.html @@ -47,7 +47,7 @@
diff --git a/docs/ch10-02-traits.html b/docs/ch10-02-traits.html index 05bdb5b..215f42f 100644 --- a/docs/ch10-02-traits.html +++ b/docs/ch10-02-traits.html @@ -47,7 +47,7 @@
diff --git a/docs/ch10-03-lifetime-syntax.html b/docs/ch10-03-lifetime-syntax.html index 7c1dc7e..8007384 100644 --- a/docs/ch10-03-lifetime-syntax.html +++ b/docs/ch10-03-lifetime-syntax.html @@ -47,7 +47,7 @@
diff --git a/docs/ch11-00-testing.html b/docs/ch11-00-testing.html index 7bf34b8..69661f8 100644 --- a/docs/ch11-00-testing.html +++ b/docs/ch11-00-testing.html @@ -47,7 +47,7 @@
diff --git a/docs/ch11-01-writing-tests.html b/docs/ch11-01-writing-tests.html index 02ef5eb..193f581 100644 --- a/docs/ch11-01-writing-tests.html +++ b/docs/ch11-01-writing-tests.html @@ -47,7 +47,7 @@
diff --git a/docs/ch11-02-running-tests.html b/docs/ch11-02-running-tests.html index 2e07afe..88e4f4f 100644 --- a/docs/ch11-02-running-tests.html +++ b/docs/ch11-02-running-tests.html @@ -47,7 +47,7 @@
diff --git a/docs/ch11-03-test-organization.html b/docs/ch11-03-test-organization.html index 6fe3148..b5f4509 100644 --- a/docs/ch11-03-test-organization.html +++ b/docs/ch11-03-test-organization.html @@ -47,7 +47,7 @@
diff --git a/docs/ch12-00-an-io-project.html b/docs/ch12-00-an-io-project.html index ff5f78c..81f349a 100644 --- a/docs/ch12-00-an-io-project.html +++ b/docs/ch12-00-an-io-project.html @@ -47,7 +47,7 @@
diff --git a/docs/ch12-01-accepting-command-line-arguments.html b/docs/ch12-01-accepting-command-line-arguments.html index a827d2e..5b19e73 100644 --- a/docs/ch12-01-accepting-command-line-arguments.html +++ b/docs/ch12-01-accepting-command-line-arguments.html @@ -47,7 +47,7 @@
diff --git a/docs/ch12-02-reading-a-file.html b/docs/ch12-02-reading-a-file.html index 9fb759f..55c546b 100644 --- a/docs/ch12-02-reading-a-file.html +++ b/docs/ch12-02-reading-a-file.html @@ -47,7 +47,7 @@
diff --git a/docs/ch12-03-improving-error-handling-and-modularity.html b/docs/ch12-03-improving-error-handling-and-modularity.html index 62000e1..f69346b 100644 --- a/docs/ch12-03-improving-error-handling-and-modularity.html +++ b/docs/ch12-03-improving-error-handling-and-modularity.html @@ -47,7 +47,7 @@
diff --git a/docs/ch12-04-testing-the-librarys-functionality.html b/docs/ch12-04-testing-the-librarys-functionality.html index ba41941..d9bf378 100644 --- a/docs/ch12-04-testing-the-librarys-functionality.html +++ b/docs/ch12-04-testing-the-librarys-functionality.html @@ -47,7 +47,7 @@
diff --git a/docs/ch12-05-working-with-environment-variables.html b/docs/ch12-05-working-with-environment-variables.html index 1565161..a2b82e2 100644 --- a/docs/ch12-05-working-with-environment-variables.html +++ b/docs/ch12-05-working-with-environment-variables.html @@ -47,7 +47,7 @@
diff --git a/docs/ch12-06-writing-to-stderr-instead-of-stdout.html b/docs/ch12-06-writing-to-stderr-instead-of-stdout.html index 1fd28a0..a7e15b9 100644 --- a/docs/ch12-06-writing-to-stderr-instead-of-stdout.html +++ b/docs/ch12-06-writing-to-stderr-instead-of-stdout.html @@ -47,7 +47,7 @@
diff --git a/docs/ch13-00-functional-features.html b/docs/ch13-00-functional-features.html index f4a5b91..e73b62d 100644 --- a/docs/ch13-00-functional-features.html +++ b/docs/ch13-00-functional-features.html @@ -47,7 +47,7 @@
diff --git a/docs/ch13-01-closures.html b/docs/ch13-01-closures.html index 98fa4a0..e818fbf 100644 --- a/docs/ch13-01-closures.html +++ b/docs/ch13-01-closures.html @@ -47,7 +47,7 @@
diff --git a/docs/ch13-02-iterators.html b/docs/ch13-02-iterators.html index 4063bae..9879d09 100644 --- a/docs/ch13-02-iterators.html +++ b/docs/ch13-02-iterators.html @@ -47,7 +47,7 @@
diff --git a/docs/ch13-03-improving-our-io-project.html b/docs/ch13-03-improving-our-io-project.html index 4f3e29c..502dc72 100644 --- a/docs/ch13-03-improving-our-io-project.html +++ b/docs/ch13-03-improving-our-io-project.html @@ -47,7 +47,7 @@
diff --git a/docs/ch13-04-performance.html b/docs/ch13-04-performance.html index 2e3f368..bfc2b1b 100644 --- a/docs/ch13-04-performance.html +++ b/docs/ch13-04-performance.html @@ -47,7 +47,7 @@
diff --git a/docs/ch14-00-more-about-cargo.html b/docs/ch14-00-more-about-cargo.html index 6405e11..93b1ef3 100644 --- a/docs/ch14-00-more-about-cargo.html +++ b/docs/ch14-00-more-about-cargo.html @@ -47,7 +47,7 @@
diff --git a/docs/ch14-01-release-profiles.html b/docs/ch14-01-release-profiles.html index 773fbff..d4723f6 100644 --- a/docs/ch14-01-release-profiles.html +++ b/docs/ch14-01-release-profiles.html @@ -47,7 +47,7 @@
diff --git a/docs/ch14-02-publishing-to-crates-io.html b/docs/ch14-02-publishing-to-crates-io.html index 008e04b..d0e6765 100644 --- a/docs/ch14-02-publishing-to-crates-io.html +++ b/docs/ch14-02-publishing-to-crates-io.html @@ -47,7 +47,7 @@
diff --git a/docs/ch14-03-cargo-workspaces.html b/docs/ch14-03-cargo-workspaces.html index 571be4b..2226d44 100644 --- a/docs/ch14-03-cargo-workspaces.html +++ b/docs/ch14-03-cargo-workspaces.html @@ -47,7 +47,7 @@
diff --git a/docs/ch14-04-installing-binaries.html b/docs/ch14-04-installing-binaries.html index acd8138..0c7ac8f 100644 --- a/docs/ch14-04-installing-binaries.html +++ b/docs/ch14-04-installing-binaries.html @@ -47,7 +47,7 @@
diff --git a/docs/ch14-05-extending-cargo.html b/docs/ch14-05-extending-cargo.html index 5bd262f..7d9a610 100644 --- a/docs/ch14-05-extending-cargo.html +++ b/docs/ch14-05-extending-cargo.html @@ -47,7 +47,7 @@
diff --git a/docs/ch15-00-smart-pointers.html b/docs/ch15-00-smart-pointers.html index ea6a570..327c05d 100644 --- a/docs/ch15-00-smart-pointers.html +++ b/docs/ch15-00-smart-pointers.html @@ -47,7 +47,7 @@
diff --git a/docs/ch15-01-box.html b/docs/ch15-01-box.html index 43c5b43..936764c 100644 --- a/docs/ch15-01-box.html +++ b/docs/ch15-01-box.html @@ -47,7 +47,7 @@
diff --git a/docs/ch15-02-deref.html b/docs/ch15-02-deref.html index 3179ded..1682672 100644 --- a/docs/ch15-02-deref.html +++ b/docs/ch15-02-deref.html @@ -47,7 +47,7 @@
diff --git a/docs/ch15-03-drop.html b/docs/ch15-03-drop.html index 6fe1034..80813e6 100644 --- a/docs/ch15-03-drop.html +++ b/docs/ch15-03-drop.html @@ -47,7 +47,7 @@
diff --git a/docs/ch15-04-rc.html b/docs/ch15-04-rc.html index e32a1a6..6183874 100644 --- a/docs/ch15-04-rc.html +++ b/docs/ch15-04-rc.html @@ -47,7 +47,7 @@
diff --git a/docs/ch15-05-interior-mutability.html b/docs/ch15-05-interior-mutability.html index f31e541..fdeb465 100644 --- a/docs/ch15-05-interior-mutability.html +++ b/docs/ch15-05-interior-mutability.html @@ -47,7 +47,7 @@
diff --git a/docs/ch15-06-reference-cycles.html b/docs/ch15-06-reference-cycles.html index a652da1..f25d60b 100644 --- a/docs/ch15-06-reference-cycles.html +++ b/docs/ch15-06-reference-cycles.html @@ -47,7 +47,7 @@
diff --git a/docs/ch16-00-concurrency.html b/docs/ch16-00-concurrency.html index e33ad66..1edaa67 100644 --- a/docs/ch16-00-concurrency.html +++ b/docs/ch16-00-concurrency.html @@ -47,7 +47,7 @@
diff --git a/docs/ch16-01-threads.html b/docs/ch16-01-threads.html index 1cfd0c3..e575dc6 100644 --- a/docs/ch16-01-threads.html +++ b/docs/ch16-01-threads.html @@ -47,7 +47,7 @@
diff --git a/docs/ch16-02-message-passing.html b/docs/ch16-02-message-passing.html index e4d6ca1..27a66f7 100644 --- a/docs/ch16-02-message-passing.html +++ b/docs/ch16-02-message-passing.html @@ -47,7 +47,7 @@
diff --git a/docs/ch16-03-shared-state.html b/docs/ch16-03-shared-state.html index 39410da..458d9ed 100644 --- a/docs/ch16-03-shared-state.html +++ b/docs/ch16-03-shared-state.html @@ -47,7 +47,7 @@
diff --git a/docs/ch16-04-extensible-concurrency-sync-and-send.html b/docs/ch16-04-extensible-concurrency-sync-and-send.html index a8de178..dff96ad 100644 --- a/docs/ch16-04-extensible-concurrency-sync-and-send.html +++ b/docs/ch16-04-extensible-concurrency-sync-and-send.html @@ -47,7 +47,7 @@
diff --git a/docs/ch17-00-oop.html b/docs/ch17-00-oop.html index 8320019..0e83dfd 100644 --- a/docs/ch17-00-oop.html +++ b/docs/ch17-00-oop.html @@ -47,7 +47,7 @@
diff --git a/docs/ch17-01-what-is-oo.html b/docs/ch17-01-what-is-oo.html index 4cdb3e9..f0dbbf8 100644 --- a/docs/ch17-01-what-is-oo.html +++ b/docs/ch17-01-what-is-oo.html @@ -47,7 +47,7 @@
diff --git a/docs/ch17-02-trait-objects.html b/docs/ch17-02-trait-objects.html index ef36460..832e99c 100644 --- a/docs/ch17-02-trait-objects.html +++ b/docs/ch17-02-trait-objects.html @@ -47,7 +47,7 @@
diff --git a/docs/ch17-03-oo-design-patterns.html b/docs/ch17-03-oo-design-patterns.html index bd4398d..f8efd9d 100644 --- a/docs/ch17-03-oo-design-patterns.html +++ b/docs/ch17-03-oo-design-patterns.html @@ -47,7 +47,7 @@
@@ -434,6 +434,10 @@ fn main() { + +
@@ -444,6 +448,10 @@ fn main() { + +
diff --git a/docs/ch18-00-patterns.html b/docs/ch18-00-patterns.html new file mode 100644 index 0000000..046c6d8 --- /dev/null +++ b/docs/ch18-00-patterns.html @@ -0,0 +1,125 @@ + + + + + 模式用来匹配值的结构 - Rust 程序设计语言 简体中文版 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+

模式用来匹配值的结构

+
+

ch18-00-patterns.md +
+commit 3d47ebddad51b0080a19857e1495675a8e9376ef

+
+

模式是 Rust 中特殊的语法,它用来匹配类型中的结构,无论类型是简单还是复杂。模式由一些常量组成;解构数组、枚举、结构体或者是元组;变量、通配符和占位符。这些部分描述了我们要处理的数据的“形状”。

+

我们通过将一些值与模式相比较来使用它。如果模式匹配这些值,我们对值部分进行相应处理。回忆一下第六章讨论 match 表达式时像硬币分类器那样使用模式。我们可以为形状中的片段命名,就像在第六章中命名出现在二十五美分硬币上的州那样,如果数据符合这个形状,就可以使用这些命名的片段。

+

本章是所有模式相关内容的参考。我们将涉及到使用模式的有效位置,refutableirrefutable 模式的区别,和你可能会见到的不同类型的模式语法。

+ +
+ + + + + + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + + diff --git a/docs/ch18-01-all-the-places-for-patterns.html b/docs/ch18-01-all-the-places-for-patterns.html new file mode 100644 index 0000000..3861b41 --- /dev/null +++ b/docs/ch18-01-all-the-places-for-patterns.html @@ -0,0 +1,228 @@ + + + + + 所有可能会用到模式的位置 - Rust 程序设计语言 简体中文版 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+

所有可能会用到模式的位置

+
+

ch18-01-all-the-places-for-patterns.md +
+commit 4ca9e513e532a4d229ab5af7dfcc567129623bf4

+
+

模式出现在 Rust 的很多地方。你已经在不经意间使用了很多模式!本部分是一个所有有效模式位置的参考。

+

match 分支

+

如第六章所讨论的,一个模式常用的位置是 match 表达式的分支。在形式上 match 表达式由 match 关键字、用于匹配的值和一个或多个分支构成。这些分支包含一个模式和在值匹配分支的模式时运行的表达式:

+
match VALUE {
+    PATTERN => EXPRESSION,
+    PATTERN => EXPRESSION,
+    PATTERN => EXPRESSION,
+}
+
+

穷尽性和默认模式 _

+

match 表达式必须是穷尽的。当我们把所有分支的模式都放在一起,match 表达式所有可能的值都应该被考虑到。一个确保覆盖每个可能值的方法是在最后一个分支使用捕获所有的模式,比如一个变量名。一个匹配任何值的名称永远也不会失败,因此可以覆盖之前分支模式匹配剩下的情况。

+

这有一个额外的模式经常被用于结尾的分支:_。它匹配所有情况,不过它从不绑定任何变量。这在例如只希望在某些模式下运行代码而忽略其他值的时候很有用。

+

if let 表达式

+

第六章讨论过了 if let 表达式,以及它是如何成为编写等同于只关心一个情况的 match 语句的简写的。if let 可以对应一个可选的 else 和代码在 if let 中的模式不匹配时运行。

+

列表 18-1 展示了甚至可以组合并匹配 if letelse ifelse if let。这些代码展示了一系列针对不同条件的检查来决定背景颜色应该是什么。为了达到这个例子的目的,我们创建了硬编码值的变量,在真实程序中则可能由询问用户获得。如果用户指定了中意的颜色,我们将使用它作为背景颜色。如果今天是星期二,背景颜色将是绿色。如果用户指定了他们的年龄字符串并能够成功将其解析为数字的话,我们将根据这个数字使用紫色或者橙色。最后,如果没有一个条件符合,背景颜色将是蓝色:

+

文件名: src/main.rs

+
fn main() {
+    let favorite_color: Option<&str> = None;
+    let is_tuesday = false;
+    let age: Result<u8, _> = "34".parse();
+
+    if let Some(color) = favorite_color {
+        println!("Using your favorite color, {}, as the background", color);
+    } else if is_tuesday {
+        println!("Tuesday is green day!");
+    } else if let Ok(age) = age {
+        if age > 30 {
+            println!("Using purple as the background color");
+        } else {
+            println!("Using orange as the background color");
+        }
+    } else {
+        println!("Using blue as the background color");
+    }
+}
+
+

列表 18-1: 结合 if letelse ifelse if letelse

+

这个条件结构允许我们支持复杂的需求。使用这里硬编码的值,例子会打印出 Using purple as the background color

+

注意 if let 也可以像 match 分支那样引入覆盖变量:if let Ok(age) = age 引入了一个新的覆盖变量 age,它包含 Ok 成员中的值。这也意味着 if age > 30 条件需要位于这个代码块内部;不能将两个条件组合为 if let Ok(age) = age && age > 30,因为我们希望与 30 进行比较的被覆盖的 age 直到大括号开始的新作用域才是有效的。

+

另外注意这样有很多情况的条件并没有 match 表达式强大,因为其穷尽性没有为编译器所检查。如果去掉最后的 else 块而遗漏处理一些情况,编译器也不会报错。这个例子可能过于复杂以致难以重写为一个可读的 match,所以需要额外注意处理了所有的情况,因为编译器不会为我们检查穷尽性。

+

while let

+

一个与 if let 类似的结构体是 while let:它允许只要模式匹配就一直进行 while 循环。列表 18-2 展示了一个使用 while let 的例子,它使用 vector 作为栈并打以先进后出的方式打印出 vector 中的值:

+
let mut stack = Vec::new();
+
+stack.push(1);
+stack.push(2);
+stack.push(3);
+
+while let Some(top) = stack.pop() {
+    println!("{}", top);
+}
+
+

列表 18-2: 使用 while let 循环只要 stack.pop() 返回 Some就打印出其值

+

这个例子会打印出 3、2 和 1。pop 方法取出 vector 的最后一个元素并返回Some(value),如果 vector 是空的,它返回 Nonewhile 循环只要 pop 返回 Some 就会一直运行其块中的代码。一旦其返回 Nonewhile循环停止。我们可以使用 while let 来弹出栈中的每一个元素。

+

for 循环

+

for 循环,如同第三章所讲的,是 Rust 中最常见的循环结构。那一章所没有讲到的是 for 可以获取一个模式。列表 18-3 中展示了如何使用 for 循环来解构一个元组。enumerate 方法适配一个迭代器来产生元组,其包含值和值的索引:

+
let v = vec![1, 2, 3];
+
+for (index, value) in v.iter().enumerate() {
+    println!("{} is at index {}", value, index);
+}
+
+

列表 18-3: 在 for 循环中使用模式来解构 enumerate 返回的元组

+

这会打印出:

+
1 is at index 0
+2 is at index 1
+3 is at index 2
+
+

第一个 enumerate 调用会产生元组 (0, 1)。当这个匹配模式 (index, value)index 将会是 0 而 value 将会是 1。

+

let 语句

+

matchif let 都是本书之前明确讨论过的使用模式的位置,不过他们不是仅有的使用过模式的地方。例如,考虑一下这个直白的 let 变量赋值:

+
let x = 5;
+
+

本书进行了不下百次这样的操作。你可能没有发觉,不过你这正是在使用模式!let 语句更为正式的样子如下:

+
let PATTERN = EXPRESSION;
+
+

我们见过的像 let x = 5; 这样的语句中变量名位于 PATTERN 位置;变量名不过是形式特别朴素的模式。

+

通过 let,我们将表达式与模式比较,并为任何找到的名称赋值。所以例如 let x = 5; 的情况,x 是一个模式代表“将匹配到的值绑定到变量 x”。同时因为名称 x 是整个模式,这个模式实际上等于“将任何值绑定到变量 x,不过它是什么”。

+

为了更清楚的理解 let 的模式匹配的方面,考虑列表 18-4 中使用 let 和模式解构一个元组:

+
let (x, y, z) = (1, 2, 3);
+
+

列表 18-4: 使用模式解构元组并一次创建三个变量

+

这里有一个元组与模式匹配。Rust 会比较值 (1, 2, 3) 与模式 (x, y, z) 并发现值匹配这个模式。在这个例子中,将会把 1 绑定到 x2 绑定到 y3 绑定到 z。你可以将这个元组模式看作是将三个独立的变量模式结合在一起。

+

在第十六章中我们见过另一个解构元组的例子,列表 16-6 中,那里解构 mpsc::channel() 的返回值为 tx(发送者)和 rx(接收者)。

+

函数参数

+

类似于 let,函数参数也可以是模式。列表 18-5 中的代码声明了一个叫做 foo 的函数,它获取一个 i32 类型的参数 x,这看起来应该很熟悉:

+
fn foo(x: i32) {
+    // code goes here
+}
+
+

列表 18-5: 在参数中使用模式的函数签名

+

x 部分就是一个模式!类似于之前对 let 所做的,可以在函数参数中匹配元组。列表 18-6 展示了如何可以将传递给函数的元组拆分为值:

+

文件名: src/main.rs

+
fn print_coordinates(&(x, y): &(i32, i32)) {
+    println!("Current location: ({}, {})", x, y);
+}
+
+fn main() {
+    let point = (3, 5);
+    print_coordinates(&point);
+}
+
+

列表 18-6: 一个在参数中解构元组的函数

+

这会打印出 Current location: (3, 5)。当传递值 &(3, 5)print_coordinates 时,这个值会匹配模式 &(x, y)x 得到了值 3,而 y得到了值 5。

+

因为如第十三章所讲闭包类似于函数,也可以在闭包参数中使用模式。

+

在这些可以使用模式的位置中的一个区别是,对于 for 循环、let 和函数参数,其模式必须是 irrefutable 的。接下来让我们讨论这个。

+ +
+ + + + + + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + + diff --git a/docs/ch18-02-refutability.html b/docs/ch18-02-refutability.html new file mode 100644 index 0000000..5409d23 --- /dev/null +++ b/docs/ch18-02-refutability.html @@ -0,0 +1,116 @@ + + + + + refutable:何时模式可能会匹配失败 - Rust 程序设计语言 简体中文版 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ +
+ + + + + + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + + diff --git a/docs/ch18-03-pattern-syntax.html b/docs/ch18-03-pattern-syntax.html new file mode 100644 index 0000000..7c79f53 --- /dev/null +++ b/docs/ch18-03-pattern-syntax.html @@ -0,0 +1,108 @@ + + + + + 模式的全部语法 - Rust 程序设计语言 简体中文版 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ +
+ + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + diff --git a/docs/index.html b/docs/index.html index 2e5e563..3b01e99 100644 --- a/docs/index.html +++ b/docs/index.html @@ -46,7 +46,7 @@
diff --git a/docs/print.html b/docs/print.html index bc57858..2c0ed6a 100644 --- a/docs/print.html +++ b/docs/print.html @@ -2,7 +2,7 @@ - 面向对象设计模式的实现 - Rust 程序设计语言 简体中文版 + 模式的全部语法 - Rust 程序设计语言 简体中文版 @@ -47,7 +47,7 @@
@@ -10344,6 +10344,127 @@ fn main() {

总结

阅读本章后,不管你是否认为 Rust 是一个面向对象语言,现在你都见识了 trait 对象是一个 Rust 中获取部分面向对象功能的方法。动态分发可以通过牺牲一些运行时性能来为你的代码提供一些灵活性。这些灵活性可以用来实现有助于代码可维护性的面向对象模式。Rust 也有像所有权这样不同于面向对象语言的功能。面向对象模式并不总是利用 Rust 实力的最好方式。

接下来,让我们看看另一个提供了很多灵活性的 Rust 功能:模式。贯穿本书我们都曾简单的见过他们,但并没有见识过他们的全部本领。让我们开始吧!

+

模式用来匹配值的结构

+
+

ch18-00-patterns.md +
+commit 3d47ebddad51b0080a19857e1495675a8e9376ef

+
+

模式是 Rust 中特殊的语法,它用来匹配类型中的结构,无论类型是简单还是复杂。模式由一些常量组成;解构数组、枚举、结构体或者是元组;变量、通配符和占位符。这些部分描述了我们要处理的数据的“形状”。

+

我们通过将一些值与模式相比较来使用它。如果模式匹配这些值,我们对值部分进行相应处理。回忆一下第六章讨论 match 表达式时像硬币分类器那样使用模式。我们可以为形状中的片段命名,就像在第六章中命名出现在二十五美分硬币上的州那样,如果数据符合这个形状,就可以使用这些命名的片段。

+

本章是所有模式相关内容的参考。我们将涉及到使用模式的有效位置,refutableirrefutable 模式的区别,和你可能会见到的不同类型的模式语法。

+

所有可能会用到模式的位置

+
+

ch18-01-all-the-places-for-patterns.md +
+commit 4ca9e513e532a4d229ab5af7dfcc567129623bf4

+
+

模式出现在 Rust 的很多地方。你已经在不经意间使用了很多模式!本部分是一个所有有效模式位置的参考。

+

match 分支

+

如第六章所讨论的,一个模式常用的位置是 match 表达式的分支。在形式上 match 表达式由 match 关键字、用于匹配的值和一个或多个分支构成。这些分支包含一个模式和在值匹配分支的模式时运行的表达式:

+
match VALUE {
+    PATTERN => EXPRESSION,
+    PATTERN => EXPRESSION,
+    PATTERN => EXPRESSION,
+}
+
+

穷尽性和默认模式 _

+

match 表达式必须是穷尽的。当我们把所有分支的模式都放在一起,match 表达式所有可能的值都应该被考虑到。一个确保覆盖每个可能值的方法是在最后一个分支使用捕获所有的模式,比如一个变量名。一个匹配任何值的名称永远也不会失败,因此可以覆盖之前分支模式匹配剩下的情况。

+

这有一个额外的模式经常被用于结尾的分支:_。它匹配所有情况,不过它从不绑定任何变量。这在例如只希望在某些模式下运行代码而忽略其他值的时候很有用。

+

if let 表达式

+

第六章讨论过了 if let 表达式,以及它是如何成为编写等同于只关心一个情况的 match 语句的简写的。if let 可以对应一个可选的 else 和代码在 if let 中的模式不匹配时运行。

+

列表 18-1 展示了甚至可以组合并匹配 if letelse ifelse if let。这些代码展示了一系列针对不同条件的检查来决定背景颜色应该是什么。为了达到这个例子的目的,我们创建了硬编码值的变量,在真实程序中则可能由询问用户获得。如果用户指定了中意的颜色,我们将使用它作为背景颜色。如果今天是星期二,背景颜色将是绿色。如果用户指定了他们的年龄字符串并能够成功将其解析为数字的话,我们将根据这个数字使用紫色或者橙色。最后,如果没有一个条件符合,背景颜色将是蓝色:

+

文件名: src/main.rs

+
fn main() {
+    let favorite_color: Option<&str> = None;
+    let is_tuesday = false;
+    let age: Result<u8, _> = "34".parse();
+
+    if let Some(color) = favorite_color {
+        println!("Using your favorite color, {}, as the background", color);
+    } else if is_tuesday {
+        println!("Tuesday is green day!");
+    } else if let Ok(age) = age {
+        if age > 30 {
+            println!("Using purple as the background color");
+        } else {
+            println!("Using orange as the background color");
+        }
+    } else {
+        println!("Using blue as the background color");
+    }
+}
+
+

列表 18-1: 结合 if letelse ifelse if letelse

+

这个条件结构允许我们支持复杂的需求。使用这里硬编码的值,例子会打印出 Using purple as the background color

+

注意 if let 也可以像 match 分支那样引入覆盖变量:if let Ok(age) = age 引入了一个新的覆盖变量 age,它包含 Ok 成员中的值。这也意味着 if age > 30 条件需要位于这个代码块内部;不能将两个条件组合为 if let Ok(age) = age && age > 30,因为我们希望与 30 进行比较的被覆盖的 age 直到大括号开始的新作用域才是有效的。

+

另外注意这样有很多情况的条件并没有 match 表达式强大,因为其穷尽性没有为编译器所检查。如果去掉最后的 else 块而遗漏处理一些情况,编译器也不会报错。这个例子可能过于复杂以致难以重写为一个可读的 match,所以需要额外注意处理了所有的情况,因为编译器不会为我们检查穷尽性。

+

while let

+

一个与 if let 类似的结构体是 while let:它允许只要模式匹配就一直进行 while 循环。列表 18-2 展示了一个使用 while let 的例子,它使用 vector 作为栈并打以先进后出的方式打印出 vector 中的值:

+
let mut stack = Vec::new();
+
+stack.push(1);
+stack.push(2);
+stack.push(3);
+
+while let Some(top) = stack.pop() {
+    println!("{}", top);
+}
+
+

列表 18-2: 使用 while let 循环只要 stack.pop() 返回 Some就打印出其值

+

这个例子会打印出 3、2 和 1。pop 方法取出 vector 的最后一个元素并返回Some(value),如果 vector 是空的,它返回 Nonewhile 循环只要 pop 返回 Some 就会一直运行其块中的代码。一旦其返回 Nonewhile循环停止。我们可以使用 while let 来弹出栈中的每一个元素。

+

for 循环

+

for 循环,如同第三章所讲的,是 Rust 中最常见的循环结构。那一章所没有讲到的是 for 可以获取一个模式。列表 18-3 中展示了如何使用 for 循环来解构一个元组。enumerate 方法适配一个迭代器来产生元组,其包含值和值的索引:

+
let v = vec![1, 2, 3];
+
+for (index, value) in v.iter().enumerate() {
+    println!("{} is at index {}", value, index);
+}
+
+

列表 18-3: 在 for 循环中使用模式来解构 enumerate 返回的元组

+

这会打印出:

+
1 is at index 0
+2 is at index 1
+3 is at index 2
+
+

第一个 enumerate 调用会产生元组 (0, 1)。当这个匹配模式 (index, value)index 将会是 0 而 value 将会是 1。

+

let 语句

+

matchif let 都是本书之前明确讨论过的使用模式的位置,不过他们不是仅有的使用过模式的地方。例如,考虑一下这个直白的 let 变量赋值:

+
let x = 5;
+
+

本书进行了不下百次这样的操作。你可能没有发觉,不过你这正是在使用模式!let 语句更为正式的样子如下:

+
let PATTERN = EXPRESSION;
+
+

我们见过的像 let x = 5; 这样的语句中变量名位于 PATTERN 位置;变量名不过是形式特别朴素的模式。

+

通过 let,我们将表达式与模式比较,并为任何找到的名称赋值。所以例如 let x = 5; 的情况,x 是一个模式代表“将匹配到的值绑定到变量 x”。同时因为名称 x 是整个模式,这个模式实际上等于“将任何值绑定到变量 x,不过它是什么”。

+

为了更清楚的理解 let 的模式匹配的方面,考虑列表 18-4 中使用 let 和模式解构一个元组:

+
let (x, y, z) = (1, 2, 3);
+
+

列表 18-4: 使用模式解构元组并一次创建三个变量

+

这里有一个元组与模式匹配。Rust 会比较值 (1, 2, 3) 与模式 (x, y, z) 并发现值匹配这个模式。在这个例子中,将会把 1 绑定到 x2 绑定到 y3 绑定到 z。你可以将这个元组模式看作是将三个独立的变量模式结合在一起。

+

在第十六章中我们见过另一个解构元组的例子,列表 16-6 中,那里解构 mpsc::channel() 的返回值为 tx(发送者)和 rx(接收者)。

+

函数参数

+

类似于 let,函数参数也可以是模式。列表 18-5 中的代码声明了一个叫做 foo 的函数,它获取一个 i32 类型的参数 x,这看起来应该很熟悉:

+
fn foo(x: i32) {
+    // code goes here
+}
+
+

列表 18-5: 在参数中使用模式的函数签名

+

x 部分就是一个模式!类似于之前对 let 所做的,可以在函数参数中匹配元组。列表 18-6 展示了如何可以将传递给函数的元组拆分为值:

+

文件名: src/main.rs

+
fn print_coordinates(&(x, y): &(i32, i32)) {
+    println!("Current location: ({}, {})", x, y);
+}
+
+fn main() {
+    let point = (3, 5);
+    print_coordinates(&point);
+}
+
+

列表 18-6: 一个在参数中解构元组的函数

+

这会打印出 Current location: (3, 5)。当传递值 &(3, 5)print_coordinates 时,这个值会匹配模式 &(x, y)x 得到了值 3,而 y得到了值 5。

+

因为如第十三章所讲闭包类似于函数,也可以在闭包参数中使用模式。

+

在这些可以使用模式的位置中的一个区别是,对于 for 循环、let 和函数参数,其模式必须是 irrefutable 的。接下来让我们讨论这个。

diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 9520f6b..cf6c5e7 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -96,4 +96,10 @@ - [什么是面向对象?](ch17-01-what-is-oo.md) - [为使用不同类型的值而设计的 trait 对象](ch17-02-trait-objects.md) - [面向对象设计模式的实现](ch17-03-oo-design-patterns.md) - \ No newline at end of file + +## 高级主题 + +- [模式用来匹配值的结构](ch18-00-patterns.md) + - [所有可能会用到模式的位置](ch18-01-all-the-places-for-patterns.md) + - [refutable:何时模式可能会匹配失败](ch18-02-refutability.md) + - [模式的全部语法](ch18-03-pattern-syntax.md) \ No newline at end of file diff --git a/src/ch18-00-patterns.md b/src/ch18-00-patterns.md new file mode 100644 index 0000000..ab9cec1 --- /dev/null +++ b/src/ch18-00-patterns.md @@ -0,0 +1,11 @@ +# 模式用来匹配值的结构 + +> [ch18-00-patterns.md](https://github.com/rust-lang/book/blob/master/second-edition/src/ch18-00-patterns.md) +>
+> commit 3d47ebddad51b0080a19857e1495675a8e9376ef + +模式是 Rust 中特殊的语法,它用来匹配类型中的结构,无论类型是简单还是复杂。模式由一些常量组成;解构数组、枚举、结构体或者是元组;变量、通配符和占位符。这些部分描述了我们要处理的数据的“形状”。 + +我们通过将一些值与模式相比较来使用它。如果模式匹配这些值,我们对值部分进行相应处理。回忆一下第六章讨论 `match` 表达式时像硬币分类器那样使用模式。我们可以为形状中的片段命名,就像在第六章中命名出现在二十五美分硬币上的州那样,如果数据符合这个形状,就可以使用这些命名的片段。 + +本章是所有模式相关内容的参考。我们将涉及到使用模式的有效位置,*refutable* 与 *irrefutable* 模式的区别,和你可能会见到的不同类型的模式语法。 diff --git a/src/ch18-01-all-the-places-for-patterns.md b/src/ch18-01-all-the-places-for-patterns.md new file mode 100644 index 0000000..84fe08e --- /dev/null +++ b/src/ch18-01-all-the-places-for-patterns.md @@ -0,0 +1,172 @@ +## 所有可能会用到模式的位置 + +> [ch18-01-all-the-places-for-patterns.md](https://github.com/rust-lang/book/blob/master/second-edition/src/ch18-01-all-the-places-for-patterns.md) +>
+> commit 4ca9e513e532a4d229ab5af7dfcc567129623bf4 + +模式出现在 Rust 的很多地方。你已经在不经意间使用了很多模式!本部分是一个所有有效模式位置的参考。 + +### `match` 分支 + +如第六章所讨论的,一个模式常用的位置是 `match` 表达式的分支。在形式上 `match` 表达式由 `match` 关键字、用于匹配的值和一个或多个分支构成。这些分支包含一个模式和在值匹配分支的模式时运行的表达式: + +``` +match VALUE { + PATTERN => EXPRESSION, + PATTERN => EXPRESSION, + PATTERN => EXPRESSION, +} +``` + +#### 穷尽性和默认模式 `_` + +`match` 表达式必须是穷尽的。当我们把所有分支的模式都放在一起,`match` 表达式所有可能的值都应该被考虑到。一个确保覆盖每个可能值的方法是在最后一个分支使用捕获所有的模式,比如一个变量名。一个匹配任何值的名称永远也不会失败,因此可以覆盖之前分支模式匹配剩下的情况。 + +这有一个额外的模式经常被用于结尾的分支:`_`。它匹配所有情况,不过它从不绑定任何变量。这在例如只希望在某些模式下运行代码而忽略其他值的时候很有用。 + +### `if let` 表达式 + +第六章讨论过了 `if let` 表达式,以及它是如何成为编写等同于只关心一个情况的 `match` 语句的简写的。`if let` 可以对应一个可选的 `else` 和代码在 `if let` 中的模式不匹配时运行。 + +列表 18-1 展示了甚至可以组合并匹配 `if let`、`else if` 和 `else if let`。这些代码展示了一系列针对不同条件的检查来决定背景颜色应该是什么。为了达到这个例子的目的,我们创建了硬编码值的变量,在真实程序中则可能由询问用户获得。如果用户指定了中意的颜色,我们将使用它作为背景颜色。如果今天是星期二,背景颜色将是绿色。如果用户指定了他们的年龄字符串并能够成功将其解析为数字的话,我们将根据这个数字使用紫色或者橙色。最后,如果没有一个条件符合,背景颜色将是蓝色: + +文件名: src/main.rs + +```rust +fn main() { + let favorite_color: Option<&str> = None; + let is_tuesday = false; + let age: Result = "34".parse(); + + if let Some(color) = favorite_color { + println!("Using your favorite color, {}, as the background", color); + } else if is_tuesday { + println!("Tuesday is green day!"); + } else if let Ok(age) = age { + if age > 30 { + println!("Using purple as the background color"); + } else { + println!("Using orange as the background color"); + } + } else { + println!("Using blue as the background color"); + } +} +``` + +列表 18-1: 结合 `if let`、`else if`、`else if let` 和 `else` + +这个条件结构允许我们支持复杂的需求。使用这里硬编码的值,例子会打印出 `Using purple as the background color`。 + +注意 `if let` 也可以像 `match` 分支那样引入覆盖变量:`if let Ok(age) = age` 引入了一个新的覆盖变量 `age`,它包含 `Ok` 成员中的值。这也意味着 `if age > 30` 条件需要位于这个代码块内部;不能将两个条件组合为 `if let Ok(age) = age && age > 30`,因为我们希望与 30 进行比较的被覆盖的 `age` 直到大括号开始的新作用域才是有效的。 + +另外注意这样有很多情况的条件并没有 `match` 表达式强大,因为其穷尽性没有为编译器所检查。如果去掉最后的 `else` 块而遗漏处理一些情况,编译器也不会报错。这个例子可能过于复杂以致难以重写为一个可读的 `match`,所以需要额外注意处理了所有的情况,因为编译器不会为我们检查穷尽性。 + +### `while let` + +一个与 `if let` 类似的结构体是 `while let`:它允许只要模式匹配就一直进行 `while` 循环。列表 18-2 展示了一个使用 `while let` 的例子,它使用 vector 作为栈并打以先进后出的方式打印出 vector 中的值: + +```rust +let mut stack = Vec::new(); + +stack.push(1); +stack.push(2); +stack.push(3); + +while let Some(top) = stack.pop() { + println!("{}", top); +} +``` + +列表 18-2: 使用 `while let` 循环只要 `stack.pop()` 返回 `Some`就打印出其值 + +这个例子会打印出 3、2 和 1。`pop` 方法取出 vector 的最后一个元素并返回`Some(value)`,如果 vector 是空的,它返回 `None`。`while` 循环只要 `pop` 返回 `Some` 就会一直运行其块中的代码。一旦其返回 `None`,`while`循环停止。我们可以使用 `while let` 来弹出栈中的每一个元素。 + +### `for` 循环 + +`for` 循环,如同第三章所讲的,是 Rust 中最常见的循环结构。那一章所没有讲到的是 `for` 可以获取一个模式。列表 18-3 中展示了如何使用 `for` 循环来解构一个元组。`enumerate` 方法适配一个迭代器来产生元组,其包含值和值的索引: + +```rust +let v = vec![1, 2, 3]; + +for (index, value) in v.iter().enumerate() { + println!("{} is at index {}", value, index); +} +``` + +列表 18-3: 在 `for` 循环中使用模式来解构 `enumerate` 返回的元组 + +这会打印出: + +``` +1 is at index 0 +2 is at index 1 +3 is at index 2 +``` + +第一个 `enumerate` 调用会产生元组 `(0, 1)`。当这个匹配模式 `(index, value)`,`index` 将会是 0 而 `value` 将会是 1。 + +### `let` 语句 + +`match` 和 `if let` 都是本书之前明确讨论过的使用模式的位置,不过他们不是仅有的**使用过**模式的地方。例如,考虑一下这个直白的 `let` 变量赋值: + +```rust +let x = 5; +``` + +本书进行了不下百次这样的操作。你可能没有发觉,不过你这正是在使用模式!`let` 语句更为正式的样子如下: + +``` +let PATTERN = EXPRESSION; +``` + +我们见过的像 `let x = 5;` 这样的语句中变量名位于 `PATTERN` 位置;变量名不过是形式特别朴素的模式。 + +通过 `let`,我们将表达式与模式比较,并为任何找到的名称赋值。所以例如 `let x = 5;` 的情况,`x` 是一个模式代表“将匹配到的值绑定到变量 x”。同时因为名称 `x` 是整个模式,这个模式实际上等于“将任何值绑定到变量 `x`,不过它是什么”。 + +为了更清楚的理解 `let` 的模式匹配的方面,考虑列表 18-4 中使用 `let` 和模式解构一个元组: + +```rust +let (x, y, z) = (1, 2, 3); +``` + +列表 18-4: 使用模式解构元组并一次创建三个变量 + +这里有一个元组与模式匹配。Rust 会比较值 `(1, 2, 3)` 与模式 `(x, y, z)` 并发现值匹配这个模式。在这个例子中,将会把 `1` 绑定到 `x`,`2` 绑定到 `y`, `3` 绑定到 `z`。你可以将这个元组模式看作是将三个独立的变量模式结合在一起。 + +在第十六章中我们见过另一个解构元组的例子,列表 16-6 中,那里解构 `mpsc::channel()` 的返回值为 `tx`(发送者)和 `rx`(接收者)。 + +### 函数参数 + +类似于 `let`,函数参数也可以是模式。列表 18-5 中的代码声明了一个叫做 `foo` 的函数,它获取一个 `i32` 类型的参数 `x`,这看起来应该很熟悉: + +```rust +fn foo(x: i32) { + // code goes here +} +``` + +列表 18-5: 在参数中使用模式的函数签名 + +`x` 部分就是一个模式!类似于之前对 `let` 所做的,可以在函数参数中匹配元组。列表 18-6 展示了如何可以将传递给函数的元组拆分为值: + +文件名: src/main.rs + +```rust +fn print_coordinates(&(x, y): &(i32, i32)) { + println!("Current location: ({}, {})", x, y); +} + +fn main() { + let point = (3, 5); + print_coordinates(&point); +} +``` + +列表 18-6: 一个在参数中解构元组的函数 + +这会打印出 `Current location: (3, 5)`。当传递值 `&(3, 5)` 给 `print_coordinates` 时,这个值会匹配模式 `&(x, y)`,`x` 得到了值 3,而 `y`得到了值 5。 + +因为如第十三章所讲闭包类似于函数,也可以在闭包参数中使用模式。 + +在这些可以使用模式的位置中的一个区别是,对于 `for` 循环、`let` 和函数参数,其模式必须是 *irrefutable* 的。接下来让我们讨论这个。 \ No newline at end of file diff --git a/src/ch18-02-refutability.md b/src/ch18-02-refutability.md new file mode 100644 index 0000000..e69de29 diff --git a/src/ch18-03-pattern-syntax.md b/src/ch18-03-pattern-syntax.md new file mode 100644 index 0000000..e69de29