From 1689863a6178a692854d12fce375318c415a42a9 Mon Sep 17 00:00:00 2001 From: KaiserY Date: Mon, 16 Dec 2019 09:49:26 +0800 Subject: [PATCH] check to ch13-02 --- src/ch13-01-closures.md | 12 +++++------- src/ch13-02-iterators.md | 18 +++++++++--------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/ch13-01-closures.md b/src/ch13-01-closures.md index d273255..2c4e0cd 100644 --- a/src/ch13-01-closures.md +++ b/src/ch13-01-closures.md @@ -2,7 +2,7 @@ > [ch13-01-closures.md](https://github.com/rust-lang/book/blob/master/src/ch13-01-closures.md) >
-> commit 1fedfc4b96c2017f64ecfcf41a0a07e2e815f24f +> commit 26565efc3f62d9dacb7c2c6d0f5974360e459493 Rust 的 **闭包**(*closures*)是可以保存进变量或作为参数传递给其他函数的匿名函数。可以在一个地方创建闭包,然后在不同的上下文中执行闭包运算。不同于函数,闭包允许捕获调用者作用域中的值。我们将展示闭包的这些功能如何复用代码和自定义行为。 @@ -98,8 +98,6 @@ fn generate_workout(intensity: u32, random_number: u32) { 示例 13-3 中的代码有多处调用了慢计算函数 `simulated_expensive_calculation` 。第一个 `if` 块调用了 `simulated_expensive_calculation` 两次, `else` 中的 `if` 没有调用它,而第二个 `else` 中的代码调用了它一次。 - - `generate_workout` 函数的期望行为是首先检查用户需要低强度(由小于 25 的系数表示)锻炼还是高强度(25 或以上)锻炼。 低强度锻炼计划会根据由 `simulated_expensive_calculation` 函数所模拟的复杂算法建议一定数量的俯卧撑和仰卧起坐。 @@ -178,7 +176,7 @@ let expensive_closure = |num| { 闭包定义是 `expensive_closure` 赋值的 `=` 之后的部分。闭包的定义以一对竖线(`|`)开始,在竖线中指定闭包的参数;之所以选择这个语法是因为它与 Smalltalk 和 Ruby 的闭包定义类似。这个闭包有一个参数 `num`;如果有多于一个参数,可以使用逗号分隔,比如 `|param1, param2|`。 -参数之后是存放闭包体的大括号 —— 如果闭包体只有一行则大括号是可以省略的。大括号之后闭包的结尾,需要用于 `let` 语句的分号。因为闭包体的最后一行没有分号(正如函数体一样),所以其返回了值 `num` 。 +参数之后是存放闭包体的大括号 —— 如果闭包体只有一行则大括号是可以省略的。大括号之后闭包的结尾,需要用于 `let` 语句的分号。因为闭包体的最后一行没有分号(正如函数体一样),所以闭包体(`num`)最后一行的返回值作为调用闭包时的返回值 。 注意这个 `let` 语句意味着 `expensive_closure` 包含一个匿名函数的 **定义**,不是调用匿名函数的 **返回值**。回忆一下使用闭包的原因是我们需要在一个位置定义代码,储存代码,并在之后的位置实际调用它;期望调用的代码现在储存在 `expensive_closure` 中。 @@ -282,7 +280,7 @@ error[E0308]: mismatched types | | let n = example_closure(5); | ^ expected struct `std::string::String`, found - integral variable + integer | = note: expected type `std::string::String` found type `{integer}` @@ -298,7 +296,7 @@ error[E0308]: mismatched types 为了让结构体存放闭包,我们需要指定闭包的类型,因为结构体定义需要知道其每一个字段的类型。每一个闭包实例有其自己独有的匿名类型:也就是说,即便两个闭包有着相同的签名,他们的类型仍然可以被认为是不同。为了定义使用闭包的结构体、枚举或函数参数,需要像第十章讨论的那样使用泛型和 trait bound。 -`Fn` 系列 trait 由标准库提供。所有的闭包都实现了 trait `Fn`、`FnMut` 或 `FnOnce` 中的一个。在“闭包会捕获其环境”部分我们会讨论这些 trait 的区别;在这个例子中可以使用 `Fn` trait。 +`Fn` 系列 trait 由标准库提供。所有的闭包都实现了 trait `Fn`、`FnMut` 或 `FnOnce` 中的一个。在 [“闭包会捕获其环境”](#capturing-the-environment-with-closures) 部分我们会讨论这些 trait 的区别;在这个例子中可以使用 `Fn` trait。 为了满足 `Fn` trait bound 我们增加了代表闭包所必须的参数和返回值类型的类型。在这个例子中,闭包有一个 `u32` 的参数并返回一个 `u32`,这样所指定的 trait bound 就是 `Fn(u32) -> u32`。 @@ -321,7 +319,7 @@ struct Cacher > 注意:函数也都实现了这三个 `Fn` trait。如果不需要捕获环境中的值,则可以使用实现了 `Fn` trait 的函数而不是闭包。 -`value` 是 `Option` 类型的。在执行闭包之前,`value` 将是 `None`。如果使用 `Cacher` 的代码请求闭包的结果,这时会执行闭包并将结果储存在 `value` 字段的 `Some` 成员中。接着如果代码再次请求闭包的结果,这时不再执行闭包,而是会返回存放在 `Some` 成员中的结果。 +字段 `value` 是 `Option` 类型的。在执行闭包之前,`value` 将是 `None`。如果使用 `Cacher` 的代码请求闭包的结果,这时会执行闭包并将结果储存在 `value` 字段的 `Some` 成员中。接着如果代码再次请求闭包的结果,这时不再执行闭包,而是会返回存放在 `Some` 成员中的结果。 刚才讨论的有关 `value` 字段逻辑定义于示例 13-10: diff --git a/src/ch13-02-iterators.md b/src/ch13-02-iterators.md index 97f028a..99b2f34 100644 --- a/src/ch13-02-iterators.md +++ b/src/ch13-02-iterators.md @@ -2,11 +2,11 @@ > [ch13-02-iterators.md](https://github.com/rust-lang/book/blob/master/src/ch13-02-iterators.md) >
-> commit 1fedfc4b96c2017f64ecfcf41a0a07e2e815f24f +> commit 8edf0457ab571b375b87357e1353ae0dd2127abe 迭代器模式允许你对一个项的序列进行某些处理。**迭代器**(*iterator*)负责遍历序列中的每一项和决定序列何时结束的逻辑。当使用迭代器时,我们无需重新实现这些逻辑。 -在 Rust 中,迭代器是**惰性的**(*lazy*),这意味着在调用方法使用迭代器之前它都不会有效果。例如,示例 13-13 中的代码通过调用定义于 `Vec` 上的 `iter` 方法在一个 vector `v1` 上创建了一个迭代器。这段代码本身没有任何用处: +在 Rust 中,迭代器是 **惰性的**(*lazy*),这意味着在调用方法使用迭代器之前它都不会有效果。例如,示例 13-13 中的代码通过调用定义于 `Vec` 上的 `iter` 方法在一个 vector `v1` 上创建了一个迭代器。这段代码本身没有任何用处: ```rust let v1 = vec![1, 2, 3]; @@ -16,7 +16,7 @@ let v1_iter = v1.iter(); 示例 13-13:创建一个迭代器 -一旦创建迭代器之后,可以选择用多种方式利用它。在示例 3-4 中,我们使用迭代器和 `for` 循环在每一个项上执行了一些代码,虽然直到现在为止我们一直没有具体讨论调用 `iter` 到底具体做了什么。 +一旦创建迭代器之后,可以选择用多种方式利用它。在第三章的示例 3-5 中,我们使用迭代器和 `for` 循环在每一个项上执行了一些代码,虽然直到现在为止我们一直没有具体讨论调用 `iter` 到底具体做了什么。 示例 13-14 中的例子将迭代器的创建和 `for` 循环中的使用分开。迭代器被储存在 `v1_iter` 变量中,而这时没有进行迭代。一旦 `for` 循环开始使用 `v1_iter`,接着迭代器中的每一个元素被用于循环的一次迭代,这会打印出其每一个值: @@ -41,7 +41,7 @@ for val in v1_iter { 迭代器都实现了一个叫做 `Iterator` 的定义于标准库的 trait。这个 trait 的定义看起来像这样: ```rust -trait Iterator { +pub trait Iterator { type Item; fn next(&mut self) -> Option; @@ -134,7 +134,7 @@ and do nothing unless consumed 示例 13-17 中的代码实际上并没有做任何事;所指定的闭包从未被调用过。警告提醒了我们为什么:迭代器适配器是惰性的,而这里我们需要消费迭代器。 -为了修复这个警告并消费迭代器获取有用的结果,我们将使用第十二章简要讲到的 `collect` 方法。这个方法消费迭代器并将结果收集到一个数据结构中。 +为了修复这个警告并消费迭代器获取有用的结果,我们将使用第十二章示例 12-1 结合 `env::args` 使用的 `collect` 方法。这个方法消费迭代器并将结果收集到一个数据结构中。 在示例 13-18 中,我们将遍历由 `map` 调用生成的迭代器的结果收集到一个 vector 中,它将会含有原始 vector 中每个元素加 1 的结果: @@ -197,7 +197,7 @@ fn filters_by_size() { `shoes_in_my_size` 函数获取一个鞋子 vector 的所有权和一个鞋子大小作为参数。它返回一个只包含指定大小鞋子的 vector。 -`shoes_in_my_size` 函数调用了 `into_iter` 来创建一个获取 vector 所有权的迭代器。接着调用 `filter` 将这个迭代器适配成一个只含有那些闭包返回 `true` 的元素的新迭代器。 +`shoes_in_my_size` 函数体中调用了 `into_iter` 来创建一个获取 vector 所有权的迭代器。接着调用 `filter` 将这个迭代器适配成一个只含有那些闭包返回 `true` 的元素的新迭代器。 闭包从环境中捕获了 `shoe_size` 变量并使用其值与每一只鞋的大小作比较,只保留指定大小的鞋子。最终,调用 `collect` 将迭代器适配器返回的值收集进一个 vector 并返回。 @@ -321,14 +321,14 @@ fn calling_next_directly() { # } # # impl Iterator for Counter { -# // Our iterator will produce u32s +# // 迭代器会产生 u32s # type Item = u32; # # fn next(&mut self) -> Option { -# // increment our count. This is why we started at zero. +# // count 自增 1。也就是为什么从 0 开始。 # self.count += 1; # -# // check to see if we've finished counting or not. +# // 检测是否结束结束计数。 # if self.count < 6 { # Some(self.count) # } else {