diff options
| author | Josh Stone <jistone@redhat.com> | 2017-06-20 15:25:51 -0700 |
|---|---|---|
| committer | Josh Stone <jistone@redhat.com> | 2017-06-20 15:25:51 -0700 |
| commit | b4038977a39f7c5bfa76cccf586930ec57befbad (patch) | |
| tree | b93b87a762f7ea17657804ec3653b374bb0c7d64 /src/libcore | |
| parent | 29bce6e220f6fd2292d13d65fe503af7bf4852b7 (diff) | |
| download | rust-b4038977a39f7c5bfa76cccf586930ec57befbad.tar.gz rust-b4038977a39f7c5bfa76cccf586930ec57befbad.zip | |
Add `Iterator::for_each`
This works like a `for` loop in functional style, applying a closure to every item in the `Iterator`. It doesn't allow `break`/`continue` like a `for` loop, nor any other control flow outside the closure, but it may be a more legible style for tying up the end of a long iterator chain. This was tried before in #14911, but nobody made the case for using it with longer iterators. There was also `Iterator::advance` at that time which was more capable than `for_each`, but that no longer exists. The `itertools` crate has `Itertools::foreach` with the same behavior, but thankfully the names won't collide. The `rayon` crate also has a `ParallelIterator::for_each` where simple `for` loops aren't possible. > I really wish we had `for_each` on seq iterators. Having to use a > dummy operation is annoying. - [@nikomatsakis][1] [1]: https://github.com/nikomatsakis/rayon/pull/367#issuecomment-308455185
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/iter/iterator.rs | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 30d09e5453b..49c43d133e5 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -482,6 +482,52 @@ pub trait Iterator { Map{iter: self, f: f} } + /// Calls a closure on each element of an iterator. + /// + /// This is equivalent to using a [`for`] loop on the iterator, although + /// `break` and `continue` are not possible from a closure. It's generally + /// more idiomatic to use a `for` loop, but `for_each` may be more legible + /// when processing items at the end of longer iterator chains. + /// + /// [`for`]: ../../book/first-edition/loops.html#for + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(iterator_for_each)] + /// + /// let mut v = vec![]; + /// (0..5).for_each(|x| v.push(x * 100)); + /// + /// let mut v2 = vec![]; + /// for x in 0..5 { v2.push(x * 100); } + /// + /// assert_eq!(v, v2); + /// ``` + /// + /// For such a small example, the `for` loop is cleaner, but `for_each` + /// might be preferable to keep a functional style with longer iterators: + /// + /// ``` + /// #![feature(iterator_for_each)] + /// + /// (0..5).flat_map(|x| x * 100 .. x * 110) + /// .enumerate() + /// .filter(|&(i, x)| (i + x) % 3 == 0) + /// .for_each(|(i, x)| println!("{}:{}", i, x)); + /// ``` + #[inline] + #[unstable(feature = "iterator_for_each", issue = "0")] + fn for_each<F>(self, mut f: F) where + Self: Sized, F: FnMut(Self::Item), + { + for item in self { + f(item); + } + } + /// Creates an iterator which uses a closure to determine if an element /// should be yielded. /// |
