Skip to content

Commit b403897

Browse files
committed
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 rust-lang#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
1 parent 29bce6e commit b403897

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# `iterator_for_each`
2+
3+
The tracking issue for this feature is: [#TBD]
4+
5+
[#TBD]: https://github.com/rust-lang/rust/issues/TBD
6+
7+
------------------------
8+
9+
To call a closure on each element of an iterator, you can use `for_each`:
10+
11+
```rust
12+
#![feature(iterator_for_each)]
13+
14+
fn main() {
15+
(0..10).for_each(|i| println!("{}", i));
16+
}
17+
```

src/libcore/iter/iterator.rs

+46
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,52 @@ pub trait Iterator {
482482
Map{iter: self, f: f}
483483
}
484484

485+
/// Calls a closure on each element of an iterator.
486+
///
487+
/// This is equivalent to using a [`for`] loop on the iterator, although
488+
/// `break` and `continue` are not possible from a closure. It's generally
489+
/// more idiomatic to use a `for` loop, but `for_each` may be more legible
490+
/// when processing items at the end of longer iterator chains.
491+
///
492+
/// [`for`]: ../../book/first-edition/loops.html#for
493+
///
494+
/// # Examples
495+
///
496+
/// Basic usage:
497+
///
498+
/// ```
499+
/// #![feature(iterator_for_each)]
500+
///
501+
/// let mut v = vec![];
502+
/// (0..5).for_each(|x| v.push(x * 100));
503+
///
504+
/// let mut v2 = vec![];
505+
/// for x in 0..5 { v2.push(x * 100); }
506+
///
507+
/// assert_eq!(v, v2);
508+
/// ```
509+
///
510+
/// For such a small example, the `for` loop is cleaner, but `for_each`
511+
/// might be preferable to keep a functional style with longer iterators:
512+
///
513+
/// ```
514+
/// #![feature(iterator_for_each)]
515+
///
516+
/// (0..5).flat_map(|x| x * 100 .. x * 110)
517+
/// .enumerate()
518+
/// .filter(|&(i, x)| (i + x) % 3 == 0)
519+
/// .for_each(|(i, x)| println!("{}:{}", i, x));
520+
/// ```
521+
#[inline]
522+
#[unstable(feature = "iterator_for_each", issue = "0")]
523+
fn for_each<F>(self, mut f: F) where
524+
Self: Sized, F: FnMut(Self::Item),
525+
{
526+
for item in self {
527+
f(item);
528+
}
529+
}
530+
485531
/// Creates an iterator which uses a closure to determine if an element
486532
/// should be yielded.
487533
///

0 commit comments

Comments
 (0)