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
This commit is contained in:
Josh Stone 2017-06-20 15:25:51 -07:00
parent 29bce6e220
commit b4038977a3
2 changed files with 63 additions and 0 deletions

View File

@ -0,0 +1,17 @@
# `iterator_for_each`
The tracking issue for this feature is: [#TBD]
[#TBD]: https://github.com/rust-lang/rust/issues/TBD
------------------------
To call a closure on each element of an iterator, you can use `for_each`:
```rust
#![feature(iterator_for_each)]
fn main() {
(0..10).for_each(|i| println!("{}", i));
}
```

View File

@ -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.
///