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