Improve Ch13

This commit is contained in:
Unisko PENG 2023-04-25 15:38:05 +08:00
parent 50dc30a435
commit 135d0157f7

View File

@ -119,7 +119,7 @@ $ cargo run lennyp@vm-ma
闭包通常是短小的,并仅在较窄的上下文里,而非任何场景下都有意义。在这些受限的条件下,编译器就可以推断出参数与返回值的类型,类似于其能够推断出绝大多数变量类型的方式(同样也有极少数编译器需要闭包类型注解的情况)。
与变量一样,在想要提升明确性与清楚时,是可以添加类型的,只不过要付出相比严格必要更多的繁琐代价。对闭包的类型进行注解,看起来会与下面清单 13-2 中所给出的定义一样。在此示例中,这里定义了一个闭包,并将其存储在一个变量中,而非清单 13-1 中所做的那样,把闭包定义在将其作为参数加以传递的地方。
和变量一样,如果我们想增加明确性和清晰性,我们可以添加类型注释,代价是比严格意义上的必要更多的言语。注解闭包的类型,看起来会像是下面清单 13-2 中所给出的定义。在此示例中,咱们定义了一个闭包,并将其存储在变量中,而非清单 13-1 中咱们所做的,把闭包定义在咱们将其作为参数传递的地方。
文件名:`src/main.rs`
@ -134,7 +134,7 @@ let expensive_closure = |num: u32| -> u32 {
*清单 13-2在闭包中加上可选的参数与返回值类型的类型注解*
加上类型注解后,闭包的语法就更像是函数的语法了。作为比较,下面定义了一个把 `1` 加到参数的函数,以及一个有着同样行为的闭包。这里为对齐那些对应部分,这里添加了一些空格。这样就表示出了闭包语法与函数语法,除开管道使用及可选语法数量外,是如何的相似。
添加了类型注解后,闭包的语法看起来就更像函数的语法了。出于比较目的,这里咱们定义了把 `1` 加到参数的一个函数,与有着同样行为的一个闭包。咱们添加了一些空格,来对齐对应部分。这说明除了使用管道和大量的语法是可选的之外,闭包语法与函数语法是多么的相似:
```rust
fn add_one_v1 (x: u32) -> u32 { x + 1 };
@ -143,7 +143,7 @@ let add_one_v3 = |x| { x + 1 };
let add_one_v4 = |x| x + 1 ;
```
第一行给出了一个函数定义,而第二行则给出的是一个完整注解过的闭包定义。在第三行中,这里移除了那个闭包定义的类型注解。在第四行,就移出了那对花括号,由于这个闭包的函数体只有一个表达式,因此这对花括号是可选的。这些全都是有效的定义,在他们被调用时,都会产生出同样的行为。由于 `add_one_v3``add_one_v4` 中的那些类型将从他们的用中推断出来,因此这两行就要被执行的闭包被编译。这一点`let v = Vec::new();` 要么需要类型注解,或需要有某种类型的值插入到这个 `Vec`Rust 才能够推断出他的类型相似。
第一行给出了函数定义,而第二行给出了完整注解过的闭包定义。在第三行,咱们移除了闭包定义的类型注解。在第四行,由于闭包的主体只有一个表达式,因此咱们移出了那对可选的花括号。这些全都是在其被调用时,会产生出同样行为的有效定义。由于 `add_one_v3``add_one_v4` 中的类型将从他们的使用中推断出来,因此这两行就要求两个被执行的闭包能被编译出来。这与 `let v = Vec::new();` 需要类型注解,或需要有某种类型的值插入到这个 `Vec`Rust 才能够推断出类型相似。
对于闭包的定义,编译器将为其各个参数及其返回值,推断出某种具体类型。举个例子,下面清单 13-3 给出仅返回其接收到的、作为参数的值的一个较短闭包定义。此闭包除了这个示例外,并没有什么用处。请注意这里并未添加任何类型注解到这个定义。由于没有类型注解,这里就可以任何类型调用这个闭包,这里第一次是以 `String` 类型调用的。在随后尝试以整数调用 `example_closure` 时,就会得到一个错误。