1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
//! 可组合的外部迭代。 //! //! 如果您发现自己具有某种类型的集合,并且需要对所述集合的元素执行操作,那么您会很快遇到 'iterators'。 //! 迭代器在惯用的 Rust 代码中大量使用,所以值得熟悉它们。 //! //! 在解释更多内容之前,让我们讨论一下该模块的结构: //! //! # Organization //! //! 该模块主要是按类型来组织的: //! //! * [Traits] 是核心部分: 这些 traits 定义了存在哪种迭代器,以及可以使用它们进行哪些操作。这些 traits 的方法值得投入一些额外的学习时间。 //! * [Functions] 提供了一些有用的方法来创建一些基本的迭代器。 //! * [Structs] 通常是模块 traits 上各种方法的返回类型。通常,您将需要查看创建 `struct` 的方法,而不是 `struct` 本身。 //! 有关原因的更多详细信息,请参见 [实现迭代器](#implementing-iterator)。 //! //! [Traits]: #traits //! [Functions]: #functions //! [Structs]: #structs //! //! 就是这样! 让我们深入研究迭代器。 //! //! # Iterator //! //! 该模块的核心是 [`Iterator`] trait。[`Iterator`] 的核心如下所示: //! //! ``` //! trait Iterator { //! type Item; //! fn next(&mut self) -> Option<Self::Item>; //! } //! ``` //! //! 迭代器具有 [`next`] 方法,该方法在调用时将返回 [`Option`]`<Item>`。 //! [`next`] 只要有元素,它们将返回 [`Some(Item)`],一旦所有元素用尽,将返回 `None` 表示迭代已完成。 //! 各个迭代器可能选择恢复迭代,因此再次调用 [`next`] 可能会或可能不会最终在某个时候再次开始返回 [`Some(Item)`] (例如,请参见 [`TryIter`])。 //! //! //! [`Iterator`] 的完整定义还包括许多其他方法,但是它们是默认方法,基于 [`next`] 构建,因此您可以免费获得它们。 //! //! 迭代器也是可组合的,通常将它们链接在一起以进行更复杂的处理形式。有关更多详细信息,请参见下面的 [Adapters](#adapters) 部分。 //! //! [`Some(Item)`]: Some //! [`next`]: Iterator::next //! [`TryIter`]: ../../std/sync/mpsc/struct.TryIter.html //! //! # 三种迭代形式 //! //! 有三种常见的方法可以从集合中创建迭代器: //! //! * `iter()`, 在 `&T` 上迭代。 //! * `iter_mut()`, 在 `&mut T` 上迭代。 //! * `into_iter()`, 在 `T` 上迭代。 //! //! 在适当的情况下,标准库中的各种内容都可以实现这三个中的一个或多个。 //! //! # 实现迭代器 //! //! 创建自己的迭代器涉及两个步骤: 创建一个 `struct` 来保存迭代器的状态,然后为该 `struct` 实现 [`Iterator`]。 //! 这就是为什么此模块中有这么多 `struct` 的原因: 每个迭代器和迭代器适配器都有一个。 //! //! 让我们创建一个名为 `Counter` 的迭代器,该迭代器的范围从 `1` 到 `5`: //! //! ``` //! // 首先,结构体: //! //! /// 从 1 到 5 计数的迭代器 //! struct Counter { //! count: usize, //! } //! //! // 我们希望计数从一开始,所以让我们添加一个 new() 方法来提供帮助。 //! // 这不是严格必要的,但很方便。 //! // 请注意,我们将 `count` 从零开始,我们将在下面的 `next () ` 实现中看到其原因。 //! impl Counter { //! fn new() -> Counter { //! Counter { count: 0 } //! } //! } //! //! // 然后,我们为 `Counter` 实现 `Iterator`: //! //! impl Iterator for Counter { //! // 我们将使用 usize 进行计数 //! type Item = usize; //! //! // next() 是唯一需要的方法 //! fn next(&mut self) -> Option<Self::Item> { //! // 增加我们的数量。这就是为什么我们从零开始。 //! self.count += 1; //! //! // 检查我们是否已经完成计数。 //! if self.count < 6 { //! Some(self.count) //! } else { //! None //! } //! } //! } //! //! // 现在我们可以使用它了! //! //! let mut counter = Counter::new(); //! //! assert_eq!(counter.next(), Some(1)); //! assert_eq!(counter.next(), Some(2)); //! assert_eq!(counter.next(), Some(3)); //! assert_eq!(counter.next(), Some(4)); //! assert_eq!(counter.next(), Some(5)); //! assert_eq!(counter.next(), None); //! ``` //! //! 以这种方式调用 [`next`] 将重复进行。Rust 有一个构造,可以在迭代器上调用 [`next`],直到它到达 `None`。让我们接下来讨论。 //! //! 还要注意,`Iterator` 提供了内部调用 `next` 的方法的默认实现,例如 `nth` 和 `fold`。 //! 但是,如果迭代器可以在不调用 `next` 的情况下更有效地计算它们,则还可以编写方法的自定义实现,例如 `nth` 和 `fold`。 //! //! # `for` 循环和 `IntoIterator` //! //! Rust 的 `for` 循环语法实际上是迭代器的语法糖。这是 `for` 的基本示例: //! //! ``` //! let values = vec![1, 2, 3, 4, 5]; //! //! for x in values { //! println!("{}", x); //! } //! ``` //! //! 这将打印数字 1 到 5,每个数字都在各自的行上。但是您会在这里注意到: 我们从未在 vector 上调用任何东西来产生迭代器。是什么赋予了? //! //! 标准库中有一个 trait,用于将某些东西转换为迭代器: [`IntoIterator`]. //! trait 具有一个方法 [`into_iter`],该方法将实现 [`IntoIterator`] 的类型转换为迭代器。 //! 让我们再次看一下 `for` 循环,以及编译器将其转换为什么: //! //! [`into_iter`]: IntoIterator::into_iter //! //! ``` //! let values = vec![1, 2, 3, 4, 5]; //! //! for x in values { //! println!("{}", x); //! } //! ``` //! //! Rust 将其反糖化为: //! //! ``` //! let values = vec![1, 2, 3, 4, 5]; //! { //! let result = match IntoIterator::into_iter(values) { //! mut iter => loop { //! let next; //! match iter.next() { //! Some(val) => next = val, //! None => break, //! }; //! let x = next; //! let () = { println!("{}", x); }; //! }, //! }; //! result //! } //! ``` //! //! 首先,我们在值上调用 `into_iter()`。然后,我们在返回的迭代器上进行匹配,一遍又一遍地调用 [`next`],直到我们看到一个 `None`。 //! 到那时,我们 `break` 退出了循环,我们已经完成了迭代。 //! //! 这里还有一点微妙之处: 标准库包含一个有趣的 [`IntoIterator`] 实现: //! //! ```ignore (only-for-syntax-highlight) //! impl<I: Iterator> IntoIterator for I //! ``` //! //! 换句话说,所有 [`Iterator`] 都通过返回自身来实现 [`IntoIterator`]。这意味着两件事: //! //! 1. 如果要编写 [`Iterator`],则可以将其与 `for` 循环一起使用。 //! 2. 如果要创建集合,则为其实现 [`IntoIterator`] 将使您的集合可以与 `for` 循环一起使用。 //! //! # 通过引用进行迭代 //! //! 由于 [`into_iter()`] 将 `self` 作为值,因此使用 `for` 循环遍历一个集合将消耗该集合。通常,您可能需要迭代一个集合而不使用它。 //! 许多集合提供了在引用上提供迭代器的方法,通常分别称为 `iter()` 和 `iter_mut()`: //! //! ``` //! let mut values = vec![41]; //! for x in values.iter_mut() { //! *x += 1; //! } //! for x in values.iter() { //! assert_eq!(*x, 42); //! } //! assert_eq!(values.len(), 1); // `values` 仍然归此函数所有。 //! ``` //! //! 如果集合类型 `C` 提供 `iter()`,则它通常还为 `&C` 实现 `IntoIterator`,而该实现只是调用 `iter()`。 //! 同样,提供 `iter_mut()` 的集合 `C` 通常通过委派给 `iter_mut()` 来为 `&mut C` 实现 `IntoIterator`。这样可以方便快捷地实现以下目的: //! //! ``` //! let mut values = vec![41]; //! for x in &mut values { // 与 `values.iter_mut()` 相同 //! *x += 1; //! } //! for x in &values { // 与 `values.iter()` 相同 //! assert_eq!(*x, 42); //! } //! assert_eq!(values.len(), 1); //! ``` //! //! 尽管许多集合都提供 `iter()`,但并非所有人都提供 `iter_mut()`。 //! 例如,如果键的哈希值发生更改,则对 [`HashSet<T>`] 或 [`HashMap<K, V>`] 的键进行更改可能会使该集合处于不一致状态,因此这些集合仅提供 `iter()`。 //! //! [`into_iter()`]: IntoIterator::into_iter //! [`HashSet<T>`]: ../../std/collections/struct.HashSet.html //! [`HashMap<K, V>`]: ../../std/collections/struct.HashMap.html //! //! # Adapters //! //! 接受一个 [`Iterator`] 并返回另一个 [`Iterator`] 的函数通常被称为迭代器适配器,因为它们是适配器模式的一种形式。 //! //! 常见的迭代器适配器包括 [`map`],[`take`] 和 [`filter`]。 //! 有关更多信息,请参见其文档。 //! //! 如果迭代器适配器为 panics,则迭代器将处于未指定 (但内存安全) 状态。 //! 也不能保证此状态在 Rust 的各个版本中都保持不变,因此您应避免依赖 panicked 的迭代器返回的确切值。 //! //! [`map`]: Iterator::map //! [`take`]: Iterator::take //! [`filter`]: Iterator::filter //! //! # Laziness //! //! 迭代器 (和迭代器 [适配器](#adapters)) 是懒惰的)。这意味着仅仅创建一个迭代器并不会做很多事情。除非您调用 [`next`],否则什么都不会发生。 //! 当创建仅出于其副作用的迭代器时,这有时会引起混乱。 //! 例如,[`map`] 方法在其迭代的每个元素上调用一个闭包: //! //! ``` //! # #![allow(unused_must_use)] //! let v = vec![1, 2, 3, 4, 5]; //! v.iter().map(|x| println!("{}", x)); //! ``` //! //! 这将不会打印任何值,因为我们只是创建了一个迭代器,而不是使用它。编译器将警告我们这种行为: //! //! ```text //! warning: unused result that must be used: iterators are lazy and //! do nothing unless consumed //! ``` //! //! 编写 [`map`] 的副作用的惯用方式是使用 `for` 循环或调用 [`for_each`] 方法: //! //! ``` //! let v = vec![1, 2, 3, 4, 5]; //! //! v.iter().for_each(|x| println!("{}", x)); //! // or //! for x in &v { //! println!("{}", x); //! } //! ``` //! //! [`map`]: Iterator::map //! [`for_each`]: Iterator::for_each //! //! 评估迭代器的另一种常见方法是使用 [`collect`] 方法来生成新的集合。 //! //! [`collect`]: Iterator::collect //! //! # Infinity //! //! 迭代器不必一定是有限的。例如,开放式范围是一个无限迭代器: //! //! ``` //! let numbers = 0..; //! ``` //! //! 通常使用 [`take`] 迭代器适配器将无限迭代器转换为有限迭代器: //! //! ``` //! let numbers = 0..; //! let five_numbers = numbers.take(5); //! //! for number in five_numbers { //! println!("{}", number); //! } //! ``` //! //! 这将在各自的行上打印数字 `0` 至 `4`。 //! //! 请记住,无限迭代器上的方法,即使可以在有限时间内数学确定结果的方法,也可能不会终止。 //! 具体来说,通常需要遍历迭代器中每个元素的方法 (如 [`min`]) 对于任何无限迭代器都可能不会成功返回。 //! //! ```no_run //! let ones = std::iter::repeat(1); //! let least = ones.min().unwrap(); // 不好了! 无限循环! //! // `ones.min()` 导致无限循环,所以我们不会达到这一点! //! println!("The smallest number one is {}.", least); //! ``` //! //! [`take`]: Iterator::take //! [`min`]: Iterator::min //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! #![stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")] pub use self::traits::Iterator; #[unstable( feature = "step_trait", reason = "likely to be replaced by finer-grained traits", issue = "42168" )] pub use self::range::Step; #[stable(feature = "iter_empty", since = "1.2.0")] pub use self::sources::{empty, Empty}; #[stable(feature = "iter_from_fn", since = "1.34.0")] pub use self::sources::{from_fn, FromFn}; #[stable(feature = "iter_once", since = "1.2.0")] pub use self::sources::{once, Once}; #[stable(feature = "iter_once_with", since = "1.43.0")] pub use self::sources::{once_with, OnceWith}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::sources::{repeat, Repeat}; #[stable(feature = "iterator_repeat_with", since = "1.28.0")] pub use self::sources::{repeat_with, RepeatWith}; #[stable(feature = "iter_successors", since = "1.34.0")] pub use self::sources::{successors, Successors}; #[stable(feature = "fused", since = "1.26.0")] pub use self::traits::FusedIterator; #[unstable(issue = "none", feature = "inplace_iteration")] pub use self::traits::InPlaceIterable; #[unstable(feature = "trusted_len", issue = "37572")] pub use self::traits::TrustedLen; #[unstable(feature = "trusted_step", issue = "85731")] pub use self::traits::TrustedStep; #[stable(feature = "rust1", since = "1.0.0")] pub use self::traits::{ DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, IntoIterator, Product, Sum, }; #[unstable(feature = "iter_zip", issue = "83574")] pub use self::adapters::zip; #[stable(feature = "iter_cloned", since = "1.1.0")] pub use self::adapters::Cloned; #[stable(feature = "iter_copied", since = "1.36.0")] pub use self::adapters::Copied; #[stable(feature = "iterator_flatten", since = "1.29.0")] pub use self::adapters::Flatten; #[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")] pub use self::adapters::MapWhile; #[unstable(feature = "inplace_iteration", issue = "none")] pub use self::adapters::SourceIter; #[stable(feature = "iterator_step_by", since = "1.28.0")] pub use self::adapters::StepBy; #[unstable(feature = "trusted_random_access", issue = "none")] pub use self::adapters::TrustedRandomAccess; #[stable(feature = "rust1", since = "1.0.0")] pub use self::adapters::{ Chain, Cycle, Enumerate, Filter, FilterMap, FlatMap, Fuse, Inspect, Map, Peekable, Rev, Scan, Skip, SkipWhile, Take, TakeWhile, Zip, }; #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] pub use self::adapters::{Intersperse, IntersperseWith}; pub(crate) use self::adapters::process_results; mod adapters; mod range; mod sources; mod traits;