diff --git a/projects/FnMut_demo/src/main.rs b/projects/FnMut_demo/src/main.rs index 0c514f5..a186b6f 100644 --- a/projects/FnMut_demo/src/main.rs +++ b/projects/FnMut_demo/src/main.rs @@ -19,4 +19,5 @@ fn main() { r.width }); println! ("{:#?}\n{:#?}", list, sort_operations); + } diff --git a/src/Ch13_Functional_Language_Features_Iterators_and_Closures.md b/src/Ch13_Functional_Language_Features_Iterators_and_Closures.md index d7f609d..00a35e4 100644 --- a/src/Ch13_Functional_Language_Features_Iterators_and_Closures.md +++ b/src/Ch13_Functional_Language_Features_Iterators_and_Closures.md @@ -477,7 +477,7 @@ fn main() { *清单 13-9:在 `sort_by_key` 下使用 `FnMut` 闭包是允许的* -在定义用到闭包的函数或类型时,这个 `Fn` 特质是相当重要的。下一小节中,咱们将讨论迭代器。许多迭代器方法,都会取闭包参数,因此在继续学习时,请牢记这些闭包的细节! +在定义用到闭包的函数或类型时,`Fn` 特质是相当重要的。下一小节中,咱们将讨论迭代器。许多迭代器方法,都会取闭包参数,因此在继续学习时,请牢记这些闭包的细节! > 注:将清单 13-8 的代码,只加入一个地址符号 `&`,而修改成下面这样,也是工作的。这就要想想是为什么了:) @@ -557,7 +557,7 @@ pub trait Iterator { } ``` -请注意此定义使用了新的语法:`type Item` 与 `Self::Item`,他们定义着此特质下的一个 *关联类型,associated type*。在 19 章中,咱们将深入谈及关联类型。至于现在,咱们需要知道的全部,便是这段代码表明,实现 `Iterator` 特质需要咱们同时定义一个 `Item` 类型,而这个 `Item` 类型会在 `next` 方法返回值类型中用到。也就是说,`Item` 类型将是迭代器返回的类型。 +请注意此定义使用了一些新语法:`type Item` 与 `Self::Item`,他们定义着此特质下的一个 *关联类型,associated type*。在 19 章中,咱们将深入谈及关联类型。至于现在,咱们只需清楚这段代码表明,实现 `Iterator` 特质需要咱们同时定义一个 `Item` 类型,而这个 `Item` 类型会在 `next` 方法返回值类型中用到。也就是说,`Item` 类型将是迭代器返回的类型。 `Iterator` 特质只需要实现者,implementors,定义一个方法:即 `next` 方法,该方法会一次返回一个封装在 `Some` 中的迭代器条目,当迭代完毕时,就会返回 `None`。 @@ -579,17 +579,19 @@ fn iterator_demonstration() { } ``` -*清单 13-12:对迭代器上的 `next` 方法进行调用* +*清单 13-12:调用迭代器上的 `next` 方法* -请注意这里需要将 `v1_iter` 构造为可变的:调用某个迭代器上的 `next` 方法,会修改那个迭代器用于追踪其本身位于其关联序列何处的内部状态。也就是说,此代码 *消费(consumes)*,或用完(use up)了这个迭代器。每次对 `next` 的调用,都会从这个迭代器吃掉一个条目。之所以之前在使用 `for` 循环时,未曾需要将 `v1_iter` 构造为可变,是由于那个循环占据了 `v1_iter` 的所有权,而在幕后将其构造为了可变。 +请注意咱们需将 `v1_iter` 构造为可变:调用迭代器上的 `next` 方法,会修改迭代器用来追踪其位于序列中何处的内部状态。换句话说,这段代码 *消费,consumes*,或用掉,use up,了迭代器。每次对 `next` 的调用,都会吃掉迭代器的一个条目。在咱们使用 `for` 循环时,之所以不需要将 `v1_iter` 构造为可变,是由于那个循环取得了 `v1_iter` 的所有权,而在幕后将其构造为了可变。 -还要注意这里从到 `next` 的调用所获取到的那些值,都是到那个矢量中值的不可变引用。`iter` 方法产生出的,是一个不可变引用的迭代器。而在打算创建一个会取得 `v1` 所有权的迭代器,并返回自有数据时,则可以调用 `into_iter` 而非 `iter`。与此类似,当需要可变引用的迭代时,那么就可以调用 `iter_mut` 而非 `iter`。 +还要注意咱们从 `next` 的调用获取到值,都是到矢量中值的不可变引用。`iter` 方法会产生对不可变引用的迭代器。若咱们打算创建出取得 `v1` 所有权,并返回有所有权的数据时,咱们可以调用 `into_iter` 而非 `iter`。与此类似,若咱们打算对可变引用迭代,咱们可以调用 `iter_mut` 而非 `iter`。 -### 消费迭代器的一些方法 +### 消费迭代器的方法 -`Iterator` 特质有着带有由标准库提供了默认实现的几个方法;通过查阅 `Iterator` 特质的标准库 API 文档,就可以找到这些方法。他们中的一些,就在他们的定义中调用了这个 `next` 方法,这正是在实现这个 `Iterator` 特质时,不要求实现这个 `next` 方法的原因。 +**Methods that Consume the Iterator** + +`Iterator` 特质有着数个带有标准库提供的默认实现的不同方法;通过查阅 `Iterator` 特质的标准库 API 文档,咱们便可找到这些方法。他们中的一些,就在其定义中调用了 `next` 方法,而这正是咱们实现 `Iterator` 特质时,不要求实现 `next` 方法的原因。 由于调用这些调用了 `next` 方法,会耗尽迭代器,因此他们被称为 *消费适配器(consuming adaptors)*。一个例子便是 `sum` 方法,他会取得迭代器的所有权,并通过重复调用 `next`,遍历所有条目,由此消费该迭代器。在其遍历期间,他就会把各个条目,加到一个运行中的总和,并在遍历完成时返回这个总和。下面清单 13-13,有着这个 `sum` 方法运用的测试演示: