@@ -3276,6 +3276,49 @@ impl<A, B> DoubleEndedIterator for Zip<A, B> where
3276
3276
///
3277
3277
/// [`map()`]: trait.Iterator.html#method.map
3278
3278
/// [`Iterator`]: trait.Iterator.html
3279
+ ///
3280
+ /// # Notes about side effects
3281
+ ///
3282
+ /// The [`map()`] iterator implements [`DoubleEndedIterator`], meaning that
3283
+ /// you can also [`map()`] backwards:
3284
+ ///
3285
+ /// ```rust
3286
+ /// let v: Vec<i32> = vec![1, 2, 3].into_iter().rev().map(|x| x + 1).collect();
3287
+ ///
3288
+ /// assert_eq!(v, [4, 3, 2]);
3289
+ /// ```
3290
+ ///
3291
+ /// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html
3292
+ ///
3293
+ /// But if your closure has state, iterating backwards may act in a way you do
3294
+ /// not expect. Let's go through an example. First, in the forward direction:
3295
+ ///
3296
+ /// ```rust
3297
+ /// let mut c = 0;
3298
+ ///
3299
+ /// for pair in vec!['a', 'b', 'c'].into_iter()
3300
+ /// .map(|letter| { c += 1; (letter, c) }) {
3301
+ /// println!("{:?}", pair);
3302
+ /// }
3303
+ /// ```
3304
+ ///
3305
+ /// This will print "('a', 1), ('b', 2), ('c', 3)".
3306
+ ///
3307
+ /// Now consider this twist where we add a call to `rev`. This version will
3308
+ /// print `('c', 1), ('b', 2), ('a', 3)`. Note that the letters are reversed,
3309
+ /// but the values of the counter still go in order. This is because `map()` is
3310
+ /// still being called lazilly on each item, but we are popping items off the
3311
+ /// back of the vector now, instead of shifting them from the front.
3312
+ ///
3313
+ /// ```rust
3314
+ /// let mut c = 0;
3315
+ ///
3316
+ /// for pair in vec!['a', 'b', 'c'].into_iter()
3317
+ /// .map(|letter| { c += 1; (letter, c) })
3318
+ /// .rev() {
3319
+ /// println!("{:?}", pair);
3320
+ /// }
3321
+ /// ```
3279
3322
#[ must_use = "iterator adaptors are lazy and do nothing unless consumed" ]
3280
3323
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
3281
3324
#[ derive( Clone ) ]
0 commit comments