Merge pull request #869 from Rainanxu/main

修正文字描述。
pull/875/head
KaiserY 1 week ago committed by GitHub
commit 00730eb46d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -39,7 +39,7 @@ Rust 的 **闭包***closures*)是可以保存在变量中或作为参数传
闭包通常较短,并且只与特定的上下文相关,而不是适用于任意情境。在这些有限的上下文中,编译器可以推断参数和返回值的类型,类似于它推断大多数变量类型的方式(尽管在某些罕见的情况下,编译器也需要闭包的类型注解)。 闭包通常较短,并且只与特定的上下文相关,而不是适用于任意情境。在这些有限的上下文中,编译器可以推断参数和返回值的类型,类似于它推断大多数变量类型的方式(尽管在某些罕见的情况下,编译器也需要闭包的类型注解)。
类似于变量,如果我们希望增加代码的明确性和清晰度,可以添加类型注解,但代价是会使代码变得比严格必要的更冗长。为示例 13-1 中定义的闭包标注类型看起来如示例 13-2 中的定义一样。这个例子中,我们定义了一个闭包并将它保存在变量中,而不是像示例 13-1 那样在传参的地方定义它。 类似于变量,如果我们希望增加代码的明确性和清晰度,可以添加类型注解,但代价是会使代码变得比严格必要的更冗长。为示例 13-1 中定义的闭包标注类型看起来如示例 13-2 中的定义一样。这个例子中,我们定义了一个闭包并将它保存在变量中,而不是像示例 13-1 那样在传参的地方定义它。
<span class="filename">文件名src/main.rs</span> <span class="filename">文件名src/main.rs</span>
@ -76,7 +76,7 @@ let add_one_v4 = |x| x + 1 ;
{{#include ../listings/ch13-functional-features/listing-13-03/output.txt}} {{#include ../listings/ch13-functional-features/listing-13-03/output.txt}}
``` ```
第一次使用 `String` 值调用 `example_closure` 时,编译器推断出 `x` 的类型以及闭包的返回类型为 `String`。接着这些类型被锁定进闭包 `example_closure` 闭包中,如果尝试对同一闭包使用不同类型则就会得到类型错误。 第一次使用 `String` 值调用 `example_closure` 时,编译器推断出 `x` 的类型以及闭包的返回类型为 `String`。接着这些类型被锁定进闭包 `example_closure` 中,如果尝试对同一闭包使用不同类型则就会得到类型错误。
### 捕获引用或移动所有权 ### 捕获引用或移动所有权
@ -134,7 +134,7 @@ let add_one_v4 = |x| x + 1 ;
### 将捕获的值移出闭包和 `Fn` trait ### 将捕获的值移出闭包和 `Fn` trait
一旦闭包捕获了定义它的环境中的某个值的引用或所有权(也就影响了什么会被移*进*闭包,如有),闭包体中的代码则决定了在稍后执行闭包时,这些引用或值将如何处理(也就影响了什么会被移*出*闭包,如有)。闭包体可以执行以下任一操作:将一个捕获的值移出闭包,修改捕获的值,既不移动也不修改值,或者一开始就不从环境中捕获任何值。 一旦闭包捕获了定义它的环境中的某个值的引用或所有权(也就影响了什么会被移****闭包,如有),闭包体中的代码则决定了在稍后执行闭包时,这些引用或值将如何处理(也就影响了什么会被移****闭包,如有)。闭包体可以执行以下任一操作:将一个捕获的值移出闭包,修改捕获的值,既不移动也不修改值,或者一开始就不从环境中捕获任何值。
闭包捕获和处理环境中的值的方式会影响闭包实现哪些 trait而 trait 是函数和结构体指定它们可以使用哪些类型闭包的方式。根据闭包体如何处理这些值,闭包会自动、渐进地实现一个、两个或全部三个 `Fn` trait。 闭包捕获和处理环境中的值的方式会影响闭包实现哪些 trait而 trait 是函数和结构体指定它们可以使用哪些类型闭包的方式。根据闭包体如何处理这些值,闭包会自动、渐进地实现一个、两个或全部三个 `Fn` trait。

@ -103,7 +103,7 @@
*(y.deref()) *(y.deref())
``` ```
Rust 将 `*` 运算符替换为先调用 `deref` 方法再进行普通解引用的操作,如此我们便不用担心是否还需手动调用 `deref` 方法了。Rust 的这个特性可以让我们写出行为一致的代码,无论面对的是常规引用还是实现了 `Deref` 的类型。 Rust 将 `*` 运算符替换为先调用 `deref` 方法再进行普通解引用的操作,如此我们便不用担心是否还需手动调用 `deref` 方法了。Rust 的这个特性可以让我们写出行为一致的代码,无论面对的是常规引用还是实现了 `Deref` 的类型。
`deref` 方法返回值的引用,以及 `*(y.deref())` 括号外边的普通解引用仍为必须的原因在于所有权。如果 `deref` 方法直接返回值而不是值的引用,其值将被移出 `self`。在这里以及大部分使用解引用运算符的情况下我们并不希望获取 `MyBox<T>` 内部值的所有权。 `deref` 方法返回值的引用,以及 `*(y.deref())` 括号外边的普通解引用仍为必须的原因在于所有权。如果 `deref` 方法直接返回值而不是值的引用,其值将被移出 `self`。在这里以及大部分使用解引用运算符的情况下我们并不希望获取 `MyBox<T>` 内部值的所有权。

@ -141,7 +141,7 @@ Rust 会**推断**如何捕获 `v`,因为 `println!` 只需要 `v` 的引用
<span class="caption">示例 16-4: 一个具有闭包的线程,尝试使用一个在主线程中被回收的引用 `v`</span> <span class="caption">示例 16-4: 一个具有闭包的线程,尝试使用一个在主线程中被回收的引用 `v`</span>
如果 Rust 允许这段代码运行,则新建线程可能会立刻被转移到后台并完全没有机会运行。新建线程内部有一个 `v` 的引用,不过主线程立刻就使用第十五章讨论的 `drop` 丢弃了 `v`。接着当新建线程开始执行,`v` 已不再有效,所以其引用也是无效的。噢,这太糟了! 如果 Rust 允许这段代码运行,则新建线程可能会立刻被转移到后台并完全没有机会运行。新建线程内部有一个 `v` 的引用,不过主线程立刻就使用第十五章讨论的 `drop` 丢弃了 `v`。接着当新建线程开始执行,`v` 已不再有效,所以其引用也是无效的。噢,这太糟了!
为了修复示例 16-3 的编译错误,我们可以听取错误信息的建议: 为了修复示例 16-3 的编译错误,我们可以听取错误信息的建议:

Loading…
Cancel
Save