From 3b02e4241a00c343467283b8d7aff8f6223002cc Mon Sep 17 00:00:00 2001 From: "Peng Hailin," Date: Sat, 29 Apr 2023 08:37:28 +0800 Subject: [PATCH] Update Ch13 --- projects/consuming_adaptor_demo/Cargo.toml | 8 +++++++ projects/consuming_adaptor_demo/src/main.rs | 11 ++++++++++ ...anguage_Features_Iterators_and_Closures.md | 22 ++++++++++--------- src/Ch21_Appendix.md | 5 +++++ 4 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 projects/consuming_adaptor_demo/Cargo.toml create mode 100644 projects/consuming_adaptor_demo/src/main.rs diff --git a/projects/consuming_adaptor_demo/Cargo.toml b/projects/consuming_adaptor_demo/Cargo.toml new file mode 100644 index 0000000..90e1388 --- /dev/null +++ b/projects/consuming_adaptor_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "consuming_adaptor_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/consuming_adaptor_demo/src/main.rs b/projects/consuming_adaptor_demo/src/main.rs new file mode 100644 index 0000000..4ff115f --- /dev/null +++ b/projects/consuming_adaptor_demo/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + let v1 = vec! [1, 2, 3]; + + let v1_iter = v1.iter(); + + let total: i32 = v1_iter.sum(); + + assert_eq! (total, 6); + + println! ("v1: {:?}", v1); +} diff --git a/src/Ch13_Functional_Language_Features_Iterators_and_Closures.md b/src/Ch13_Functional_Language_Features_Iterators_and_Closures.md index 00a35e4..f03c4eb 100644 --- a/src/Ch13_Functional_Language_Features_Iterators_and_Closures.md +++ b/src/Ch13_Functional_Language_Features_Iterators_and_Closures.md @@ -448,7 +448,7 @@ For more information about this error, try `rustc --explain E0507`. error: could not compile `closure-example` due to previous error ``` -报错指向的是闭包主体中,把 `value` 迁出环境的那行。要修复这个问题,咱们需要修改闭包的主体,令其不将值迁出环境。要计算sort_by_key被调用的次数,在环境中保留一个计数器并在闭包体中递增其值,是一种更直接的计算方法。下面清单 13-9 中的闭包,由于只捕获了到 `num_sort_operations` 计数器的可变引用,进而就可以被多次调用,其就会工作: +报错指向的是闭包主体中,把 `value` 迁出环境的那行。要修复这个问题,咱们需要修改闭包的主体,令其不将值迁出环境。要计算 `sort_by_key` 被调用的次数,在环境中保留一个计数器并在闭包主体中递增其值,是一种更直接的计算方法。下面清单 13-9 中的闭包,由于只捕获了到 `num_sort_operations` 计数器的可变引用,进而就可以被多次调用,其就会工作: 文件名:`src/main.rs` @@ -507,7 +507,7 @@ fn main() { ``` -## 使用迭代器处理系列条目 +## 使用迭代器处理条目系列 **Processing a Series of Items with Iterators** @@ -591,9 +591,9 @@ fn iterator_demonstration() { **Methods that Consume the Iterator** -`Iterator` 特质有着数个带有标准库提供的默认实现的不同方法;通过查阅 `Iterator` 特质的标准库 API 文档,咱们便可找到这些方法。他们中的一些,就在其定义中调用了 `next` 方法,而这正是咱们实现 `Iterator` 特质时,不要求实现 `next` 方法的原因。 +`Iterator` 特质有着数个不同的,带有由标准库提供默认实现的方法;通过查阅 `Iterator` 特质的标准库 API 文档,咱们便可找到这些方法。其中一些方法,在他们的定义中会调用 `next` 方法,这就是为什么在实现 `Iterator` 特质时需要实现 `next` 方法的原因。 -由于调用这些调用了 `next` 方法,会耗尽迭代器,因此他们被称为 *消费适配器(consuming adaptors)*。一个例子便是 `sum` 方法,他会取得迭代器的所有权,并通过重复调用 `next`,遍历所有条目,由此消费该迭代器。在其遍历期间,他就会把各个条目,加到一个运行中的总和,并在遍历完成时返回这个总和。下面清单 13-13,有着这个 `sum` 方法运用的测试演示: +调用 `next` 的方法称为 *消费适配器,consuming adaptors*,因为调用它们会耗尽迭代器。一个例子是 `sum` 方法,他会获取迭代器的所有权并通过重复调用 `next` 方法来迭代项目,从而消费迭代器。在迭代过程中,他会把每个条目,加到一个运行中的总和,并在遍历完成时返回总和。下面清单 13-13,有着说明 `sum` 方法运用的测试: 文件名:`src/lib.rs` @@ -612,14 +612,16 @@ fn iterator_sum() { *清单 13-13:调用 `sum` 方法来获取迭代器中全部项目的总和* -由于 `sum` 会取得那个在其上调用他的迭代器的所有权,因此在到 `sum` 的调用之后,是不允许使用 `v1_iter` 的。 +由于 `sum` 取得了咱们于其上调用他的迭代器所有权,因此在 `sum` 的调用后,就不允许使用 `v1_iter` 了。 ### 产生其他迭代器的方法 -*迭代器适配器(iterator adaptors)* 是一些定义在 `Iterator` 特质上,不会消费迭代器的方法。相反,他们会通过改变初始迭代器的某些方面,而产生出别的一些迭代器。 +**Iterators that Produce Other Iterators** -下面清单 13-17 给出了一个调用迭代器适配器方法 `map` 的示例,该方法会取得在迭代器条目被遍历时在各个条目上调用的闭包。这个 `map` 方法会返回一个产生出修改后的那些条目的一个新迭代器。此示例中的闭包,会创建一个其中原矢量的各个条目被增加 `1` 了的新迭代器: +*迭代器适配器,iterator adaptors* 是定义在 `Iterator` 特质上,不会消费迭代器的方法。相反,他们会通过改变初始迭代器的某一方面,而产生出不同迭代器。 + +下面清单 13-17 给出了调用迭代器适配器方法 `map` 的示例,其会取迭代器条目被遍历时,在各个条目上调用的一个闭包。`map` 方法会返回产生出修改后条目的新迭代器。这里的闭包创建了一个新的迭代器,其中原矢量的各个条目都增加了 `1`: 文件名:`src/main.rs` @@ -629,7 +631,7 @@ fn iterator_sum() { v1.iter().map(|x| x + 1); ``` -*清单 13-14:调用迭代器适配器 `map` 来创建出一个新迭代器* +*清单 13-14:调用迭代器适配器 `map` 来创建出新迭代器* 然而,此代码会产生一条告警: @@ -650,9 +652,9 @@ warning: `iterator_demo` (bin "iterator_demo") generated 1 warning Running `target/debug/iterator_demo` ``` -清单 13-14 中的代码,并未执行任何事情;那里所指定的闭包不曾被调用过。那条告警提示了缘由:迭代器适配器是惰性的,进而在此就需要消费该迭代器。 +清单 13-14 中的代码没有做任何事情;咱们指定的闭包从未被调用。这个警告提醒了我们为什么:迭代器适配器是懒惰的,我们需要在这里消费迭代器。 -为修正此告警而消费那个迭代器,这里将使用 `collect` 方法,之前曾在第 12 章的清单 12-1 中,对 `env::args` 用到过该方法。此方法会消费那个迭代器,并将那些结果值,收集到一个集合数据类型中。 +为修正此告警并消费迭代器,咱们将使用 `collect` 方法,在第 12 章的清单 12-1 中,咱们曾对 `env::args` 用到过该方法。此方法会消费迭代器,并将结果值收集到一个集合数据类型中。 下面清单 13-15 中,就把在那个自 `map` 的调用所返回的迭代器遍历的结果,收集到了一个矢量值中。这个矢量将以包含原始矢量的各个条目增加 `1` 后的各个条目。 diff --git a/src/Ch21_Appendix.md b/src/Ch21_Appendix.md index 24748b5..531f382 100644 --- a/src/Ch21_Appendix.md +++ b/src/Ch21_Appendix.md @@ -795,6 +795,11 @@ $ rustup component add llvm-tools-preview Associated type, 是通过 `type` 关键字,定义在特质下的类型。咱们知道方法即为关联函数,associated function,那么关联类型自然与关联函数有些类似。 + +- 消费适配器 + +Consuming adaptor, `Iterator` 特质上,会调用到迭代器 `next` 方法的一些方法,由于这些方法会耗尽迭代器,故他们被称为消费适配器。 + - 文档注释 Documentation comment, 将产生出 HTML 的注释。