diff options
| author | bors <bors@rust-lang.org> | 2016-02-03 00:58:37 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-02-03 00:58:37 +0000 |
| commit | a9922419cf84a12b2b9c69f8b261cdd7c287c1a5 (patch) | |
| tree | 892a71c2d529580445b468a47d1b627ee5b8fbca /src/libcore | |
| parent | dea183aa8461e8520b08864ec81ad2985be36d34 (diff) | |
| parent | 1a21dabf27232c5c9281a6bf7a8b83afb3efa201 (diff) | |
| download | rust-a9922419cf84a12b2b9c69f8b261cdd7c287c1a5.tar.gz rust-a9922419cf84a12b2b9c69f8b261cdd7c287c1a5.zip | |
Auto merge of #31370 - Manishearth:rollup, r=Manishearth
- Successful merges: #27499, #31220, #31329, #31332, #31347, #31351, #31352, #31366 - Failed merges:
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/iter.rs | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 93514dbd6bb..3f1808a0396 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -1050,6 +1050,30 @@ pub trait Iterator { /// // got a false, take_while() isn't used any more /// assert_eq!(iter.next(), None); /// ``` + /// + /// Because `take_while()` needs to look at the value in order to see if it + /// should be included or not, consuming iterators will see that it is + /// removed: + /// + /// ``` + /// let a = [1, 2, 3, 4]; + /// let mut iter = a.into_iter(); + /// + /// let result: Vec<i32> = iter.by_ref() + /// .take_while(|n| **n != 3) + /// .cloned() + /// .collect(); + /// + /// assert_eq!(result, &[1, 2]); + /// + /// let result: Vec<i32> = iter.cloned().collect(); + /// + /// assert_eq!(result, &[4]); + /// ``` + /// + /// The `3` is no longer there, because it was consumed in order to see if + /// the iteration should stop, but wasn't placed back into the iterator or + /// some similar thing. #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where @@ -3258,6 +3282,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)] |
