Merge pull request #872 from Rainanxu/main

修复一些翻译问题及三处代码块问题。
pull/875/head
KaiserY 7 days ago committed by GitHub
commit f0ea5e3849
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,7 +1,7 @@
fn main() {
let some_option_value: Option<i32> = None;
// ANCHOR: here
let Some(x) = some_option_value else {
if let Some(x) = some_option_value else {
return;
};
// ANCHOR_END: here

@ -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

@ -1,7 +1,7 @@
fn main() {
// ANCHOR: here
let x = 5 else {
return;
if let x = 5 {
println!("{x}");
};
// ANCHOR_END: here
}

@ -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 <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= 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

@ -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)
@ -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)

@ -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)
@ -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)

@ -115,7 +115,7 @@ help: there is a method `try_next` with a similar name
首先,我们创建了一个返回 `impl Stream<Item = String>``get_messages` 函数。作为其实现,我们创建了一个异步信道,循环遍历英文字母表的前 10 个字母,并通过信道发送它们。
我们还使用了一个新类型:`ReceiverStream`,它将 `trpl::channel``rx` 接收端转换为一个带有带有 `next` 方法的 `Stream`。回到 `main`,我们使用了一个 `while let` 循环来打印来自流中的所有消息。
我们还使用了一个新类型:`ReceiverStream`,它将 `trpl::channel``rx` 接收端转换为一个带有 `next` 方法的 `Stream`。回到 `main`,我们使用了一个 `while let` 循环来打印来自流中的所有消息。
运行这段代码时,我们将得到与预期完全一致的结果:
@ -136,7 +136,7 @@ Message: 'i'
Message: 'j'
```
虽然再一次,我们可以使用常规的 `Receiver` API 甚至是 `Iterator` API 来做到这些,所以让我们增加一个需要流的功能:增加一个适用于流中所有项的超时,和一个发送项的延时,如示例 17-34 所示。
不过,我们可以使用常规的 `Receiver` API 甚至是 `Iterator` API 来做到这些,所以让我们增加一个需要流的功能:增加一个适用于流中所有项的超时,和一个发送项的延时,如示例 17-34 所示。
<figure class="listing">

@ -20,7 +20,7 @@ pub trait Future {
}
```
trait 定义中包含一些的新类型和我们之前没有见过新语法,所以让我们逐步详细地解析一下这个定义。
trait 定义中包含一些的新类型和我们之前没有见过新语法,所以让我们逐步详细地解析一下这个定义。
首先, `Future` 的关联类型 `Output` 表明 future 最终解析出的类型。这类似于 `Iterator` trait 的关联类型 `Item`。其次,`Future` 还有一个 `poll` 方法,其有一个特殊的 `self` 参数的 `Pin` 引用和一个 `Context` 类型的可变引用,并返回一个 `Poll<Self::Output>`。稍后我们再细说 `Pin``Context`。现在让我们专注于方法返回的 `Poll` 类型:
@ -197,7 +197,7 @@ pub trait Future {
</figure>
因此,如果 `String` 实现了 `!Unpin` 我们可以做一些非法的事,比如像图 17-9 这样在完全相同的内存位置将一个字符串替换为另一个字符串。这并不违反 `Pin` 的规则,因为 `String` 没有内部引用这使得它可以安全地移动!这是为何它实现了 `Unpin` 而不是 `!Unpin` 的原因。
因此,如果 `String` 实现了 `!Unpin` 我们可以做一些非法的事,比如像图 17-9 这样在完全相同的内存位置将一个字符串替换为另一个字符串。这并不违反 `Pin` 的规则,因为 `String` 没有内部引用这使得它可以安全地移动!这是为何它实现了 `Unpin` 而不是 `!Unpin` 的原因。
<figure>
@ -209,13 +209,13 @@ pub trait Future {
现在我们已经掌握足够的知识来理解示例 17-17 中对 `join_all` 调用所报告的错误了。最初我们尝试将异步代码块产生的 future 移动进 `Vec<Box<dyn Future<Output = ()>>>` 中,不过正如之前所见,这些 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

@ -60,7 +60,7 @@
## 总结
这并不会是本书中你最后一次接触并发。[第二一章][ch21] 中的项目会在一个更加真实的场景中运用这些概念,而不是这里讨论的简单示例,同时会更直接地比较线程和任务的解决问题方式。
这并不会是本书中你最后一次接触并发。[第二一章][ch21] 中的项目会在一个更加真实的场景中运用这些概念,而不是这里讨论的简单示例,同时会更直接地比较线程和任务的解决问题方式。
无论你选择何种方式Rust 提供了编写安全、快速和并发代码的工具 -- 无论是用于高吞吐量 web 服务器或是用于嵌入式操作系统。

@ -3,4 +3,4 @@
<!-- https://github.com/rust-lang/book/blob/main/src/ch18-00-oop.md -->
<!-- commit 56ec353290429e6547109e88afea4de027b0f1a9 -->
面向对象编程Object-Oriented ProgrammingOOP是一种对程序进行建模方式。对象Object作为一个编程概念来源于 20 世纪 60 年代的 Simula 编程语言。这些对象影响了 Alan Kay 的编程架构,该架构中对象之间互相传递消息。他于 1967 年创造了**面向对象编程***object-oriented programming*)这一术语。对于 OOP 的定义众说纷纭在一些定义下Rust 是面向对象的在其他定义下Rust 不是。在本章节中,我们会探索一些被普遍认为是面向对象的特性和这些特性是如何体现在 Rust 语言习惯中的。接着会展示如何在 Rust 中实现面向对象设计模式,并讨论这么做与利用 Rust 自身的一些优势实现的方案相比有什么取舍。
面向对象编程Object-Oriented ProgrammingOOP是一种对程序进行建模方式。对象Object作为一个编程概念来源于 20 世纪 60 年代的 Simula 编程语言。这些对象影响了 Alan Kay 的编程架构,该架构中对象之间互相传递消息。他于 1967 年创造了**面向对象编程***object-oriented programming*)这一术语。对于 OOP 的定义众说纷纭在一些定义下Rust 是面向对象的在其他定义下Rust 不是。在本章节中,我们会探索一些被普遍认为是面向对象的特性和这些特性是如何体现在 Rust 语言习惯中的。接着会展示如何在 Rust 中实现面向对象设计模式,并讨论这么做与利用 Rust 自身的一些优势实现的方案相比有什么取舍。

@ -28,9 +28,9 @@ match x {
这个 `match` 表达式中的模式为每个箭头左边的 `None``Some(i)`
`match` 表达式的一个要求是它们必须**穷尽***exhaustive*)的,意为 `match` 表达式所有可能的值都必须被考虑到。一个确保覆盖每个可能值的方法是在最后一个分支使用捕获所有的模式:比如,一个匹配任何值的名称永远也不会失败,因此可以覆盖所有匹配剩下的情况。
`match` 表达式的一个要求是它们必须**穷尽***exhaustive*)的,意为 `match` 表达式所有可能的值都必须被考虑到。一个确保覆盖每个可能值的方法是在最后一个分支使用**捕获所有**的模式:比如,一个匹配任何值的名称永远也不会失败,因此可以覆盖所有匹配剩下的情况。
有一个特定的模式 `_` 可以匹配所有情况,不过它从不绑定任何变量。这在例如希望忽略任何未指定值的情况很有用。本章之后的 [“忽略模式中的值”][ignoring-values-in-a-pattern] 部分会详细介绍 `_` 模式的更多细节。
有一个特定的模式 `_` 可以匹配所有情况,不过它从不绑定任何变量。例如这在希望忽略任何未指定值的情况很有用。本章之后的 [“忽略模式中的值”][ignoring-values-in-a-pattern] 部分会详细介绍 `_` 模式的更多细节。
### `if let` 条件表达式

@ -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}}
@ -231,7 +231,7 @@ Rust 的借用检查器无法理解我们要借用这个 slice 的两个不同
每当我们编写一个不安全函数,惯常做法是编写一个以 `SAFETY` 开头的注释并解释调用者需要做什么才可以安全地调用该方法。同理,当我们进行不安全操作时,惯常做法是编写一个以 `SAFETY` 开头并解释安全性规则是如何维护的。
另外,编译器不会允许你创建一个可变静态变量的引用。你只能通过用裸指针解引用操作符创建的裸指针访问它。这包括引用的创建不可见的情况,例如这个代码示例中用于 `println!` 的情况。可变静态变量只能通过裸指针创建的要求有助于确保使用它们的安全要求更为明确。
另外,编译器不会允许你创建一个可变静态变量的引用。你只能通过用裸指针解引用操作符创建的裸指针访问它。这包括引用的创建不可见的情况,例如这个代码示例中用于 `println!` 的情况。可变静态变量只能通过裸指针创建的要求有助于确保使用它们的安全要求更为明确。
拥有可以全局访问的可变数据,难以保证不存在数据竞争,这就是为何 Rust 认为可变静态变量是不安全的。在任何可能的情况下,请优先使用第十六章讨论的并发技术和线程安全智能指针,这样编译器就能检测不同线程间的数据访问是否是安全的。

@ -98,7 +98,7 @@ trait Add<Rhs=Self> {
### 在同名方法之间消歧义
Rust 既不能避免一个 trait 与另一个 trait 拥有相同名称的方法,也不能阻止为同一类型同时实现这两个 trait。同时可以直接在类型上实现一个与 trait 方法同名的方法。
Rust 既不能避免一个 trait 与另一个 trait 拥有相同名称的方法,也不能阻止为同一类型同时实现这两个 trait。同时可以直接在类型上实现一个与 trait 方法同名的方法。
当调用这些同名方法时,需要告诉 Rust 我们想要使用哪一个。考虑一下示例 20-17 中的代码,这里我们定义了两个 trait`Pilot` 和 `Wizard`,它们都拥有名为 `fly` 的方法。接着在一个本身已经实现了名为 `fly` 方法的类型 `Human` 上实现这两个 trait。每一个 `fly` 方法都进行了不同的操作:

Loading…
Cancel
Save