|
|
|
@ -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>
|
|
|
|
|
|
|
|
|
@ -76,7 +76,7 @@ let add_one_v4 = |x| x + 1 ;
|
|
|
|
|
{{#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
|
|
|
|
|
|
|
|
|
|
一旦闭包捕获了定义它的环境中的某个值的引用或所有权(也就影响了什么会被移*进*闭包,如有),闭包体中的代码则决定了在稍后执行闭包时,这些引用或值将如何处理(也就影响了什么会被移*出*闭包,如有)。闭包体可以执行以下任一操作:将一个捕获的值移出闭包,修改捕获的值,既不移动也不修改值,或者一开始就不从环境中捕获任何值。
|
|
|
|
|
一旦闭包捕获了定义它的环境中的某个值的引用或所有权(也就影响了什么会被移**进**闭包,如有),闭包体中的代码则决定了在稍后执行闭包时,这些引用或值将如何处理(也就影响了什么会被移**出**闭包,如有)。闭包体可以执行以下任一操作:将一个捕获的值移出闭包,修改捕获的值,既不移动也不修改值,或者一开始就不从环境中捕获任何值。
|
|
|
|
|
|
|
|
|
|
闭包捕获和处理环境中的值的方式会影响闭包实现哪些 trait,而 trait 是函数和结构体指定它们可以使用哪些类型闭包的方式。根据闭包体如何处理这些值,闭包会自动、渐进地实现一个、两个或全部三个 `Fn` trait。
|
|
|
|
|
|
|
|
|
|