about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2016-02-03 02:54:24 +0530
committerManish Goregaokar <manishsmail@gmail.com>2016-02-03 02:54:24 +0530
commitae96e51ac74ddfec533f5cd60b2bc91ec2dabcd4 (patch)
treeb0d72fc13533638cc59296e619db2c53b0a16086 /src
parent76e00250788e81a639508fd98b04a0932af0bb2c (diff)
parent7deb057d550b120aebe6576f860362cec38e3cf3 (diff)
downloadrust-ae96e51ac74ddfec533f5cd60b2bc91ec2dabcd4.tar.gz
rust-ae96e51ac74ddfec533f5cd60b2bc91ec2dabcd4.zip
Rollup merge of #31220 - steveklabnik:gh30632, r=nikomatsakis
Fixes #30632

I'm not sure if this explanation is good enough. If it is, I will add it to filter as well.
Diffstat (limited to 'src')
-rw-r--r--src/libcore/iter.rs43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 93514dbd6bb..b2736609cf7 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -3258,6 +3258,49 @@ impl<A, B> DoubleEndedIterator for Zip<A, B> where
 ///
 /// [`map()`]: trait.Iterator.html#method.map
 /// [`Iterator`]: trait.Iterator.html
+///
+/// # Notes about side effects
+///
+/// The [`map()`] iterator implements [`DoubleEndedIterator`], meaning that
+/// you can also [`map()`] backwards:
+///
+/// ```rust
+/// let v: Vec<i32> = vec![1, 2, 3].into_iter().rev().map(|x| x + 1).collect();
+///
+/// assert_eq!(v, [4, 3, 2]);
+/// ```
+///
+/// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html
+///
+/// But if your closure has state, iterating backwards may act in a way you do
+/// not expect. Let's go through an example. First, in the forward direction:
+///
+/// ```rust
+/// let mut c = 0;
+///
+/// for pair in vec!['a', 'b', 'c'].into_iter()
+///                                .map(|letter| { c += 1; (letter, c) }) {
+///     println!("{:?}", pair);
+/// }
+/// ```
+///
+/// This will print "('a', 1), ('b', 2), ('c', 3)".
+///
+/// Now consider this twist where we add a call to `rev`. This version will
+/// print `('c', 1), ('b', 2), ('a', 3)`. Note that the letters are reversed,
+/// but the values of the counter still go in order. This is because `map()` is
+/// still being called lazilly on each item, but we are popping items off the
+/// back of the vector now, instead of shifting them from the front.
+///
+/// ```rust
+/// let mut c = 0;
+///
+/// for pair in vec!['a', 'b', 'c'].into_iter()
+///                                .map(|letter| { c += 1; (letter, c) })
+///                                .rev() {
+///     println!("{:?}", pair);
+/// }
+/// ```
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]