From 0b8d03def928eb4aa929cebc80f076517102d1de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Fri, 30 May 2025 19:24:27 +0800 Subject: [PATCH 01/17] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E8=AF=8D=E8=AF=AD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch17-04-streams.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch17-04-streams.md b/src/ch17-04-streams.md index 8d0cca3..5afe1b1 100644 --- a/src/ch17-04-streams.md +++ b/src/ch17-04-streams.md @@ -115,7 +115,7 @@ help: there is a method `try_next` with a similar name 首先,我们创建了一个返回 `impl Stream` 的 `get_messages` 函数。作为其实现,我们创建了一个异步信道,循环遍历英文字母表的前 10 个字母,并通过信道发送它们。 -我们还使用了一个新类型:`ReceiverStream`,它将 `trpl::channel` 的 `rx` 接收端转换为一个带有带有 `next` 方法的 `Stream`。回到 `main`,我们使用了一个 `while let` 循环来打印来自流中的所有消息。 +我们还使用了一个新类型:`ReceiverStream`,它将 `trpl::channel` 的 `rx` 接收端转换为一个带有 `next` 方法的 `Stream`。回到 `main`,我们使用了一个 `while let` 循环来打印来自流中的所有消息。 运行这段代码时,我们将得到与预期完全一致的结果: From 8b3ed65d783b40fbe607b43f153d6546a4e7a1ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Fri, 30 May 2025 19:24:51 +0800 Subject: [PATCH 02/17] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E7=BF=BB=E8=AF=91?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch17-04-streams.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch17-04-streams.md b/src/ch17-04-streams.md index 5afe1b1..339ead5 100644 --- a/src/ch17-04-streams.md +++ b/src/ch17-04-streams.md @@ -136,7 +136,7 @@ Message: 'i' Message: 'j' ``` -虽然再一次,我们可以使用常规的 `Receiver` API 甚至是 `Iterator` API 来做到这些,所以让我们增加一个需要流的功能:增加一个适用于流中所有项的超时,和一个发送项的延时,如示例 17-34 所示。 +不过,我们可以使用常规的 `Receiver` API 甚至是 `Iterator` API 来做到这些,所以让我们增加一个需要流的功能:增加一个适用于流中所有项的超时,和一个发送项的延时,如示例 17-34 所示。
From 5efebc9c6ac5336feddf74984dbe38d05d11ee18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Fri, 30 May 2025 20:11:37 +0800 Subject: [PATCH 03/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86?= =?UTF-8?q?=E8=AF=AD=E5=8F=A5=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch17-05-traits-for-async.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ch17-05-traits-for-async.md b/src/ch17-05-traits-for-async.md index d536162..dc207d5 100644 --- a/src/ch17-05-traits-for-async.md +++ b/src/ch17-05-traits-for-async.md @@ -20,7 +20,7 @@ pub trait Future { } ``` -trait 定义中包含一些的新类型和我们之前没有见过新语法,所以让我们逐步详细地解析一下这个定义。 +trait 定义中包含一些的新类型和我们之前没有见过的新语法,所以让我们逐步详细地解析一下这个定义。 首先, `Future` 的关联类型 `Output` 表明 future 最终解析出的类型。这类似于 `Iterator` trait 的关联类型 `Item`。其次,`Future` 还有一个 `poll` 方法,其有一个特殊的 `self` 参数的 `Pin` 引用和一个 `Context` 类型的可变引用,并返回一个 `Poll`。稍后我们再细说 `Pin` 和 `Context`。现在让我们专注于方法返回的 `Poll` 类型: @@ -197,7 +197,7 @@ pub trait Future {
-因此,如果 `String` 实现了 `!Unpin` 我们可以做一些非法的事,比如像图 17-9 这样在完全相同的内存位置将一个字符串替换为另一个字符串。这并不违反 `Pin` 的规则,因为 `String` 没有内部引用这使得它可以安全地移动!这这是为何它实现了 `Unpin` 而不是 `!Unpin` 的原因。 +因此,如果 `String` 实现了 `!Unpin` 我们可以做一些非法的事,比如像图 17-9 这样在完全相同的内存位置将一个字符串替换为另一个字符串。这并不违反 `Pin` 的规则,因为 `String` 没有内部引用这使得它可以安全地移动!这是为何它实现了 `Unpin` 而不是 `!Unpin` 的原因。
From 9273486134b7c94f9748c80b0279e70c152a3434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Fri, 30 May 2025 20:15:05 +0800 Subject: [PATCH 04/17] =?UTF-8?q?=E5=B0=86=E8=AF=AD=E5=8F=A5=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E7=AC=A6=E5=90=88=E4=B8=AD=E6=96=87=E9=98=85?= =?UTF-8?q?=E8=AF=BB=E4=B9=A0=E6=83=AF=E7=9A=84=E7=BB=93=E6=9E=84=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原本的句子有种有语病的感觉。 有点过于口语化的断句会导致文本化阅读的理解障碍。 --- src/ch17-05-traits-for-async.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch17-05-traits-for-async.md b/src/ch17-05-traits-for-async.md index dc207d5..7da6905 100644 --- a/src/ch17-05-traits-for-async.md +++ b/src/ch17-05-traits-for-async.md @@ -209,7 +209,7 @@ pub trait Future { 现在我们已经掌握足够的知识来理解示例 17-17 中对 `join_all` 调用所报告的错误了。最初我们尝试将异步代码块产生的 future 移动进 `Vec>>` 中,不过正如之前所见,这些 future 可能包含内部引用,因此它们并未实现 `Unpin`。它们需要被 pin 住,接下来就可以将 `Pin` 类型传入 `Vec`,并确信 future 底层的数据**不会**被移动。 -`Pin` 和 `Unpin` 在编写底层代码库,或者在你自己编写运行时的时候最为重要,而不是在日常的 Rust 代码中。不过,现在当你在错误信息中看到这些 trait 时,就能想出更好的方式如何来修复代码了! +`Pin` 和 `Unpin` 在编写底层代码库或你自己编写运行时的时候最为重要,而不是在日常的 Rust 代码中。不过,现在当你在错误信息中看到这些 trait 时,就能想出更好的方式如何来修复代码了! > 注意:`Pin` 与 `Unpin` 的组合使得可以安全地实现在 Rust 中原本因自引用而难以实现的一整类复杂类型。要求 `Pin` 的类型在如今的异步 Rust 中最为常见,不过偶尔你也会在其它上下文中见到它们。 > From 9787308aa24e5dd9e0ecd457b55dabbb2f1d7654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Sat, 31 May 2025 10:50:06 +0800 Subject: [PATCH 05/17] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=AF=AD=E5=8F=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch17-05-traits-for-async.md | 4 ++-- src/ch17-06-futures-tasks-threads.md | 2 +- src/ch18-00-oop.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ch17-05-traits-for-async.md b/src/ch17-05-traits-for-async.md index 7da6905..51ddd81 100644 --- a/src/ch17-05-traits-for-async.md +++ b/src/ch17-05-traits-for-async.md @@ -209,13 +209,13 @@ pub trait Future { 现在我们已经掌握足够的知识来理解示例 17-17 中对 `join_all` 调用所报告的错误了。最初我们尝试将异步代码块产生的 future 移动进 `Vec>>` 中,不过正如之前所见,这些 future 可能包含内部引用,因此它们并未实现 `Unpin`。它们需要被 pin 住,接下来就可以将 `Pin` 类型传入 `Vec`,并确信 future 底层的数据**不会**被移动。 -`Pin` 和 `Unpin` 在编写底层代码库或你自己编写运行时的时候最为重要,而不是在日常的 Rust 代码中。不过,现在当你在错误信息中看到这些 trait 时,就能想出更好的方式如何来修复代码了! +`Pin` 和 `Unpin` 在编写底层代码库或你自己编写运行时的时候最为重要,而不是在日常的 Rust 代码中。不过,现在当你在错误信息中看到这些 trait 时,就能想出更好的方式来修复代码了! > 注意:`Pin` 与 `Unpin` 的组合使得可以安全地实现在 Rust 中原本因自引用而难以实现的一整类复杂类型。要求 `Pin` 的类型在如今的异步 Rust 中最为常见,不过偶尔你也会在其它上下文中见到它们。 > > `Pin` 和 `Unpin` 如何工作的细节,以及它们要求维护的规则,在 `std::pin` 的 API 文档中有详尽的介绍,所以如果你有兴趣学习更多,这是一个很好的起点。 > -> 如果你更深入地理解底层是如何实现的细节,请查看 [_Asynchronous Programming in Rust_][async-book] 的[第二章][under-the-hood]和[第四章][pinning]。 +> 如果你希望更深入地理解底层是如何实现的细节,请查看 [_Asynchronous Programming in Rust_][async-book] 的[第二章][under-the-hood]和[第四章][pinning]。 ### `Stream` trait diff --git a/src/ch17-06-futures-tasks-threads.md b/src/ch17-06-futures-tasks-threads.md index 903050f..c625d76 100644 --- a/src/ch17-06-futures-tasks-threads.md +++ b/src/ch17-06-futures-tasks-threads.md @@ -60,7 +60,7 @@ ## 总结 -这并不会是本书中你最后一次接触并发。[第二一章][ch21] 中的项目会在一个更加真实的场景中运用这些概念,而不是这里讨论的简单示例,同时会更直接地比较线程和任务的解决问题的方式。 +这并不会是本书中你最后一次接触并发。[第二一章][ch21] 中的项目会在一个更加真实的场景中运用这些概念,而不是这里讨论的简单示例,同时会更直接地比较线程和任务的解决问题方式。 无论你选择何种方式,Rust 提供了编写安全、快速和并发代码的工具 -- 无论是用于高吞吐量 web 服务器或是用于嵌入式操作系统。 diff --git a/src/ch18-00-oop.md b/src/ch18-00-oop.md index 0fa401f..368eb78 100644 --- a/src/ch18-00-oop.md +++ b/src/ch18-00-oop.md @@ -3,4 +3,4 @@ -面向对象编程(Object-Oriented Programming,OOP)是一种对程序进行建模方式。对象(Object)作为一个编程概念来源于 20 世纪 60 年代的 Simula 编程语言。这些对象影响了 Alan Kay 的编程架构,该架构中对象之间互相传递消息。他于 1967 年创造了**面向对象编程**(*object-oriented programming*)这一术语。对于 OOP 的定义众说纷纭;在一些定义下,Rust 是面向对象的;在其他定义下,Rust 不是。在本章节中,我们会探索一些被普遍认为是面向对象的特性和这些特性是如何体现在 Rust 语言习惯中的。接着会展示如何在 Rust 中实现面向对象设计模式,并讨论这么做与利用 Rust 自身的一些优势实现的方案相比有什么取舍。 +面向对象编程(Object-Oriented Programming,OOP)是一种对程序进行建模的方式。对象(Object)作为一个编程概念来源于 20 世纪 60 年代的 Simula 编程语言。这些对象影响了 Alan Kay 的编程架构,该架构中对象之间互相传递消息。他于 1967 年创造了**面向对象编程**(*object-oriented programming*)这一术语。对于 OOP 的定义众说纷纭;在一些定义下,Rust 是面向对象的;在其他定义下,Rust 不是。在本章节中,我们会探索一些被普遍认为是面向对象的特性和这些特性是如何体现在 Rust 语言习惯中的。接着会展示如何在 Rust 中实现面向对象设计模式,并讨论这么做与利用 Rust 自身的一些优势实现的方案相比有什么取舍。 From 09502155e0e39e449a0bf072fb254f066bd37c4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Sat, 31 May 2025 10:50:45 +0800 Subject: [PATCH 06/17] =?UTF-8?q?=E7=BB=9F=E4=B8=80=E3=80=90=E9=9D=A2?= =?UTF-8?q?=E5=90=91=E5=AF=B9=E8=B1=A1=E8=AF=AD=E8=A8=80=E7=9A=84=E7=89=B9?= =?UTF-8?q?=E5=BE=81=E3=80=91=E7=9A=84=E7=9B=AE=E5=BD=95=E6=A0=87=E9=A2=98?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/README.md | 2 +- src/SUMMARY.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/README.md b/src/README.md index 4f4ff2b..b386642 100644 --- a/src/README.md +++ b/src/README.md @@ -102,7 +102,7 @@ - [使用 `Sync` 与 `Send` Traits 的可扩展并发:](ch16-04-extensible-concurrency-sync-and-send.md) - [Rust 的面向对象编程特性](ch17-00-oop.md) - - [面向对象语言的特点](ch17-01-what-is-oo.md) + - [面向对象语言的特征](ch17-01-what-is-oo.md) - [顾及不同类型值的 trait 对象](ch17-02-trait-objects.md) - [面向对象设计模式的实现](ch17-03-oo-design-patterns.md) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index cc3616f..6d6d3ed 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -110,7 +110,7 @@ - [future、任务和线程](ch17-06-futures-tasks-threads.md) - [面向对象编程特性](ch18-00-oop.md) - - [面向对象语言的特点](ch18-01-what-is-oo.md) + - [面向对象语言的特征](ch18-01-what-is-oo.md) - [顾及不同类型值的 trait 对象](ch18-02-trait-objects.md) - [面向对象设计模式的实现](ch18-03-oo-design-patterns.md) From c8fe36fd66319bb77901b2974b26e7e8f57efc80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Sat, 31 May 2025 16:51:59 +0800 Subject: [PATCH 07/17] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch19-01-all-the-places-for-patterns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch19-01-all-the-places-for-patterns.md b/src/ch19-01-all-the-places-for-patterns.md index 2170f59..3278c7c 100644 --- a/src/ch19-01-all-the-places-for-patterns.md +++ b/src/ch19-01-all-the-places-for-patterns.md @@ -28,7 +28,7 @@ match x { 这个 `match` 表达式中的模式为每个箭头左边的 `None` 和 `Some(i)`。 -`match` 表达式的一个要求是它们必须**穷尽**(*exhaustive*)的,意为 `match` 表达式所有可能的值都必须被考虑到。一个确保覆盖每个可能值的方法是在最后一个分支使用捕获所有的模式:比如,一个匹配任何值的名称永远也不会失败,因此可以覆盖所有匹配剩下的情况。 +`match` 表达式的一个要求是它们必须是**穷尽**(*exhaustive*)的,意为 `match` 表达式所有可能的值都必须被考虑到。一个确保覆盖每个可能值的方法是在最后一个分支使用捕获所有的模式:比如,一个匹配任何值的名称永远也不会失败,因此可以覆盖所有匹配剩下的情况。 有一个特定的模式 `_` 可以匹配所有情况,不过它从不绑定任何变量。这在例如希望忽略任何未指定值的情况很有用。本章之后的 [“忽略模式中的值”][ignoring-values-in-a-pattern] 部分会详细介绍 `_` 模式的更多细节。 From feb45b088e080946bf5ea9482014267c8c1c70fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Sat, 31 May 2025 16:53:32 +0800 Subject: [PATCH 08/17] =?UTF-8?q?=E5=B7=AE=E5=BC=82=E5=8C=96=E7=89=B9?= =?UTF-8?q?=E5=AE=9A=E5=90=8D=E8=AF=8D=EF=BC=8C=E4=BE=BF=E4=BA=8E=E7=90=86?= =?UTF-8?q?=E8=A7=A3=E8=AF=AD=E4=B9=89=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch19-01-all-the-places-for-patterns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch19-01-all-the-places-for-patterns.md b/src/ch19-01-all-the-places-for-patterns.md index 3278c7c..439be6e 100644 --- a/src/ch19-01-all-the-places-for-patterns.md +++ b/src/ch19-01-all-the-places-for-patterns.md @@ -28,7 +28,7 @@ match x { 这个 `match` 表达式中的模式为每个箭头左边的 `None` 和 `Some(i)`。 -`match` 表达式的一个要求是它们必须是**穷尽**(*exhaustive*)的,意为 `match` 表达式所有可能的值都必须被考虑到。一个确保覆盖每个可能值的方法是在最后一个分支使用捕获所有的模式:比如,一个匹配任何值的名称永远也不会失败,因此可以覆盖所有匹配剩下的情况。 +`match` 表达式的一个要求是它们必须是**穷尽**(*exhaustive*)的,意为 `match` 表达式所有可能的值都必须被考虑到。一个确保覆盖每个可能值的方法是在最后一个分支使用**捕获所有**的模式:比如,一个匹配任何值的名称永远也不会失败,因此可以覆盖所有匹配剩下的情况。 有一个特定的模式 `_` 可以匹配所有情况,不过它从不绑定任何变量。这在例如希望忽略任何未指定值的情况很有用。本章之后的 [“忽略模式中的值”][ignoring-values-in-a-pattern] 部分会详细介绍 `_` 模式的更多细节。 From 3f2d996783929d5683f05de640642d45bce961f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Sat, 31 May 2025 17:14:27 +0800 Subject: [PATCH 09/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E8=AF=AD=E5=BA=8F=E9=94=99=E8=AF=AF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch19-01-all-the-places-for-patterns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch19-01-all-the-places-for-patterns.md b/src/ch19-01-all-the-places-for-patterns.md index 439be6e..3fdb81b 100644 --- a/src/ch19-01-all-the-places-for-patterns.md +++ b/src/ch19-01-all-the-places-for-patterns.md @@ -30,7 +30,7 @@ match x { `match` 表达式的一个要求是它们必须是**穷尽**(*exhaustive*)的,意为 `match` 表达式所有可能的值都必须被考虑到。一个确保覆盖每个可能值的方法是在最后一个分支使用**捕获所有**的模式:比如,一个匹配任何值的名称永远也不会失败,因此可以覆盖所有匹配剩下的情况。 -有一个特定的模式 `_` 可以匹配所有情况,不过它从不绑定任何变量。这在例如希望忽略任何未指定值的情况很有用。本章之后的 [“忽略模式中的值”][ignoring-values-in-a-pattern] 部分会详细介绍 `_` 模式的更多细节。 +有一个特定的模式 `_` 可以匹配所有情况,不过它从不绑定任何变量。例如这在希望忽略任何未指定值的情况很有用。本章之后的 [“忽略模式中的值”][ignoring-values-in-a-pattern] 部分会详细介绍 `_` 模式的更多细节。 ### `if let` 条件表达式 From df1083ae968c52a1eb52a6d6a2762405dcc7f585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Sat, 31 May 2025 17:17:28 +0800 Subject: [PATCH 10/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8D19-9=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E9=94=99=E8=AF=AF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- listings/ch19-patterns-and-matching/listing-19-09/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/listings/ch19-patterns-and-matching/listing-19-09/src/main.rs b/listings/ch19-patterns-and-matching/listing-19-09/src/main.rs index e974935..b430e85 100644 --- a/listings/ch19-patterns-and-matching/listing-19-09/src/main.rs +++ b/listings/ch19-patterns-and-matching/listing-19-09/src/main.rs @@ -1,7 +1,7 @@ fn main() { let some_option_value: Option = None; // ANCHOR: here - let Some(x) = some_option_value else { + if let Some(x) = some_option_value else { return; }; // ANCHOR_END: here From a50eb042c85d1300d138b6e83ac947cb2ca125fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Sat, 31 May 2025 17:20:20 +0800 Subject: [PATCH 11/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8D19-10=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E9=94=99=E8=AF=AF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- listings/ch19-patterns-and-matching/listing-19-10/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/listings/ch19-patterns-and-matching/listing-19-10/src/main.rs b/listings/ch19-patterns-and-matching/listing-19-10/src/main.rs index 6186890..5d1cc5c 100644 --- a/listings/ch19-patterns-and-matching/listing-19-10/src/main.rs +++ b/listings/ch19-patterns-and-matching/listing-19-10/src/main.rs @@ -1,6 +1,6 @@ fn main() { // ANCHOR: here - let x = 5 else { + if let x = 5 else { return; }; // ANCHOR_END: here From 7b0fa6a4bdf8810b349af881de081c89123e775d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Sat, 31 May 2025 17:27:35 +0800 Subject: [PATCH 12/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8D19-10=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=8F=8A=E5=85=B6=E7=BC=96=E8=AF=91=E8=BF=94=E8=BF=98=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../listing-19-10/output.txt | 12 ++++++------ .../listing-19-10/src/main.rs | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/listings/ch19-patterns-and-matching/listing-19-10/output.txt b/listings/ch19-patterns-and-matching/listing-19-10/output.txt index 7f825dc..1c890d5 100644 --- a/listings/ch19-patterns-and-matching/listing-19-10/output.txt +++ b/listings/ch19-patterns-and-matching/listing-19-10/output.txt @@ -1,13 +1,13 @@ $ cargo run Compiling patterns v0.1.0 (file:///projects/patterns) -warning: irrefutable `let...else` pattern - --> src/main.rs:2:5 +warning: irrefutable `if let` pattern + --> src/main.rs:2:8 | -2 | let x = 5 else { - | ^^^^^^^^^ +2 | if let x = 5 { + | ^^^^^^^^^ | - = note: this pattern will always match, so the `else` clause is useless - = help: consider removing the `else` clause + = note: this pattern will always match, so the `if let` is useless + = help: consider replacing the `if let` with a `let` = note: `#[warn(irrefutable_let_patterns)]` on by default warning: `patterns` (bin "patterns") generated 1 warning diff --git a/listings/ch19-patterns-and-matching/listing-19-10/src/main.rs b/listings/ch19-patterns-and-matching/listing-19-10/src/main.rs index 5d1cc5c..2073948 100644 --- a/listings/ch19-patterns-and-matching/listing-19-10/src/main.rs +++ b/listings/ch19-patterns-and-matching/listing-19-10/src/main.rs @@ -1,7 +1,7 @@ fn main() { // ANCHOR: here - if let x = 5 else { - return; + if let x = 5 { + println!("{x}"); }; // ANCHOR_END: here } From ece3ba62ed9f1ddb33db3a9df41d5c1c8a5c205b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Sat, 31 May 2025 19:52:29 +0800 Subject: [PATCH 13/17] =?UTF-8?q?=E7=BB=9F=E4=B8=8020-1=E7=9A=84=E6=A0=87?= =?UTF-8?q?=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/README.md | 2 +- src/SUMMARY.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/README.md b/src/README.md index b386642..f1460aa 100644 --- a/src/README.md +++ b/src/README.md @@ -114,7 +114,7 @@ - [模式语法](ch18-03-pattern-syntax.md) - [高级特征](ch19-00-advanced-features.md) - - [不安全的 Rust](ch19-01-unsafe-rust.md) + - [不安全 Rust](ch19-01-unsafe-rust.md) - [高级 trait](ch19-03-advanced-traits.md) - [高级类型](ch19-04-advanced-types.md) - [高级函数与闭包](ch19-05-advanced-functions-and-closures.md) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 6d6d3ed..245e277 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -122,7 +122,7 @@ - [模式语法](ch19-03-pattern-syntax.md) - [高级特性](ch20-00-advanced-features.md) - - [不安全的 Rust](ch20-01-unsafe-rust.md) + - [不安全 Rust](ch20-01-unsafe-rust.md) - [高级 trait](ch20-02-advanced-traits.md) - [高级类型](ch20-03-advanced-types.md) - [高级函数与闭包](ch20-04-advanced-functions-and-closures.md) From 3e0187c0ce00ccca5a35f87b3a19e75a8a4cdf27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Sat, 31 May 2025 21:20:04 +0800 Subject: [PATCH 14/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=AF=AD=E5=BA=8F?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch20-01-unsafe-rust.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ch20-01-unsafe-rust.md b/src/ch20-01-unsafe-rust.md index f946aa2..8c85609 100644 --- a/src/ch20-01-unsafe-rust.md +++ b/src/ch20-01-unsafe-rust.md @@ -72,7 +72,7 @@ 创建一个指针不会造成任何危害;只有当访问其指向的值时才有可能遇到无效的值。 -还需注意示例 20-1 和 20-3 中创建了同时指向相同内存位置 `num` 的裸指针 `*const i32` 和 `*mut i32`。相反如果尝试同时创建 `num` 的不可变和可变引用,代码将无法通过编译,因为 Rust 的所有权规则不允许在拥有任何不可变引用的同时再创建可变引用。通过裸指针,就能够同时创建同一地址的可变指针和不可变指针,若通过可变指针修改数据,则可能潜在造成数据竞争。请多加小心! +还需注意示例 20-1 和 20-3 中创建了同时指向相同内存位置 `num` 的裸指针 `*const i32` 和 `*mut i32`。相反如果尝试同时创建 `num` 的不可变和可变引用,代码将无法通过编译,因为 Rust 的所有权规则不允许在拥有任何不可变引用的同时再创建可变引用。通过裸指针,就能够同时创建同一地址的可变指针和不可变指针,若通过可变指针修改数据,则可能造成潜在数据竞争。请多加小心! 既然存在这么多的危险,为何还要使用裸指针呢?一个主要的应用场景便是调用 C 代码接口,这在下一部分 [“调用不安全函数或方法”](#调用不安全函数或方法) 中会讲到。另一个场景是构建借用检查器无法理解的安全抽象。让我们先介绍不安全函数,接着看一看使用不安全代码的安全抽象的示例。 @@ -100,7 +100,7 @@ #### 创建不安全代码的安全抽象 -仅仅因为函数包含不安全代码并不意味着整个函数都需要标记为不安全的。事实上,将不安全代码封装进安全函数是一种常见的抽象方式。作为一个例子,了解一下标准库中的函数 `split_at_mut`,它需要一些不安全代码,让我们探索如何可以实现它。这个安全函数定义于可变 slice 之上:它获取一个 slice 并从给定的索引参数开始将其分割为两个 slice。示例 20-4 展示了如何使用 `split_at_mut`。 +仅仅因为函数包含不安全代码并不意味着整个函数都需要标记为不安全的。事实上,将不安全代码封装进安全函数是一种常见的抽象方式。作为一个例子,了解一下标准库中的函数 `split_at_mut`,它需要一些不安全代码,让我们探索可以如何实现它。这个安全函数定义于可变 slice 之上:它获取一个 slice 并从给定的索引参数开始将其分割为两个 slice。示例 20-4 展示了如何使用 `split_at_mut`。 ```rust {{#rustdoc_include ../listings/ch20-advanced-features/listing-20-04/src/main.rs:here}} From 42f99efa0bb0dc307ea2fabb02f7b15bce1a7e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Sat, 31 May 2025 21:26:55 +0800 Subject: [PATCH 15/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8D20-11=E7=9A=84mimr?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5=E5=8F=8D=E9=A6=88=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原数据可能是未安装nightly 版本的 Rust 和 Miri的结果,英文原版网页运行也是这个反馈。 --- .../ch20-advanced-features/listing-20-11/output.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/listings/ch20-advanced-features/listing-20-11/output.txt b/listings/ch20-advanced-features/listing-20-11/output.txt index bf64b38..6494426 100644 --- a/listings/ch20-advanced-features/listing-20-11/output.txt +++ b/listings/ch20-advanced-features/listing-20-11/output.txt @@ -1,5 +1,16 @@ $ cargo +nightly miri run Compiling unsafe-example v0.1.0 (file:///projects/unsafe-example) Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.01s - Running `file:///home/.rustup/toolchains/nightly/bin/cargo-miri runner target/miri/debug/unsafe-example` + Running `/Users/chris/.rustup/toolchains/nightly-aarch64-apple-darwin/bin/cargo-miri runner target/miri/aarch64-apple-darwin/debug/unsafe-example` +warning: creating a shared reference to mutable static is discouraged + --> src/main.rs:14:33 + | +14 | println!("COUNTER: {}", COUNTER); + | ^^^^^^^ shared reference to mutable static + | + = note: for more information, see + = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = note: `#[warn(static_mut_refs)]` on by default + COUNTER: 3 + From b3685f5f4a45cfc3a8fba63f9688441cbe818492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Sat, 31 May 2025 21:27:25 +0800 Subject: [PATCH 16/17] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E9=94=99=E5=88=AB=E5=AD=97=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch20-01-unsafe-rust.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch20-01-unsafe-rust.md b/src/ch20-01-unsafe-rust.md index 8c85609..11c9bb2 100644 --- a/src/ch20-01-unsafe-rust.md +++ b/src/ch20-01-unsafe-rust.md @@ -231,7 +231,7 @@ Rust 的借用检查器无法理解我们要借用这个 slice 的两个不同 每当我们编写一个不安全函数,惯常做法是编写一个以 `SAFETY` 开头的注释并解释调用者需要做什么才可以安全地调用该方法。同理,当我们进行不安全操作时,惯常做法是编写一个以 `SAFETY` 开头并解释安全性规则是如何维护的。 -另外,编译器不会允许你创建一个可变静态变量的引用。你只能通过用裸指针解引用操作符创建的裸指针访问它。这包括引用的创建时不可见的情况,例如这个代码示例中用于 `println!` 的情况。可变静态变量只能通过裸指针创建的要求有助于确保使用它们的安全要求更为明确。 +另外,编译器不会允许你创建一个可变静态变量的引用。你只能通过用裸指针解引用操作符创建的裸指针访问它。这包括引用的创建是不可见的情况,例如这个代码示例中用于 `println!` 的情况。可变静态变量只能通过裸指针创建的要求有助于确保使用它们的安全要求更为明确。 拥有可以全局访问的可变数据,难以保证不存在数据竞争,这就是为何 Rust 认为可变静态变量是不安全的。在任何可能的情况下,请优先使用第十六章讨论的并发技术和线程安全智能指针,这样编译器就能检测不同线程间的数据访问是否是安全的。 From 4ae2b80d39c8a74ad2ce4cb5634e70a665467a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Sat, 31 May 2025 21:44:09 +0800 Subject: [PATCH 17/17] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=8E=AA=E8=BE=9E?= =?UTF-8?q?=EF=BC=8C=E4=BB=A5=E4=BE=BF=E4=BA=8E=E7=90=86=E8=A7=A3=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch20-02-advanced-traits.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch20-02-advanced-traits.md b/src/ch20-02-advanced-traits.md index 6282c64..a7e1e75 100644 --- a/src/ch20-02-advanced-traits.md +++ b/src/ch20-02-advanced-traits.md @@ -98,7 +98,7 @@ trait Add { ### 在同名方法之间消歧义 -Rust 既不能避免一个 trait 与另一个 trait 拥有相同名称的方法,也不能阻止为同一类型同时实现这两个 trait。同时也可以直接在类型上实现一个与 trait 方法同名的方法。 +Rust 既不能避免一个 trait 与另一个 trait 拥有相同名称的方法,也不能阻止为同一类型同时实现这两个 trait。同时还可以直接在类型上实现一个与 trait 方法同名的方法。 当调用这些同名方法时,需要告诉 Rust 我们想要使用哪一个。考虑一下示例 20-17 中的代码,这里我们定义了两个 trait,`Pilot` 和 `Wizard`,它们都拥有名为 `fly` 的方法。接着在一个本身已经实现了名为 `fly` 方法的类型 `Human` 上实现这两个 trait。每一个 `fly` 方法都进行了不同的操作: