+// ## Fun with iterators and closures
+//@ If you are familiar with functional languages, you are probably aware that one can have lots of fun with iterators and closures.
+//@ Rust provides a whole lot of methods on iterators that allow us to write pretty functional-style list manipulation.
+
+// Let's say we want to write a function that increments every entry of a `Vec` by some number, then looks for numbers larger than some threshold, and prints them.
+fn inc_print_even(v: &Vec<i32>, offset: i32, threshold: i32) {
+ //@ `map` takes a closure that is applied to every element of the iterator. `filter` removes elements
+ //@ from the iterator that do not pass the test given by the closure.
+ //@
+ //@ Since all these closures compile down to the pattern described above, there is actually no heap allocation going on here. This makes
+ //@ closures very efficient, and it makes optimization fairly trivial: The resulting code will look like you hand-rolled the loop in C.
+ for i in v.iter().map(|n| *n + offset).filter(|n| *n > threshold) {
+ println!("{}", i);
+ }
+}
+
+// Sometimes it is useful to know both the position of some element in a list, and its value. That's where the `enumerate` function helps.
+fn print_enumerated<T: fmt::Display>(v: &Vec<T>) {
+ //@ `enumerate` turns an iterator over `T` into an iterator over `(usize, T)`, where the first element just counts the position in the iterator.
+ //@ We can do pattern matching right in the loop header to obtain names for both the position, and the value.
+ for (i, t) in v.iter().enumerate() {
+ println!("Position {}: {}", i, t);
+ }
+}
+
+// And as a final example, one can also collect all elements of an iterator, and put them, e.g., in a vector.
+fn filter_vec_by_divisor(v: &Vec<i32>, divisor: i32) -> Vec<i32> {
+ //@ Here, the return type of `collect` is inferred based on the return type of our function. In general, it can return anything implementing
+ //@ [`FromIterator`](https://doc.rust-lang.org/stable/std/iter/trait.FromIterator.html). Notice that `iter` gives us an iterator over
+ //@ borrowed `i32`, but we want to own them for the result, so we insert a `map` to dereference.
+ v.iter().map(|n| *n).filter(|n| *n % divisor == 0).collect() /*@*/
+}
+
+// **Exercise 10.1**: Look up the [documentation of `Iterator`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html) to learn about more functions
+// that can act on iterators. Try using some of them. What about a function that sums the even numbers of an iterator? Or a function that computes the
+// product of those numbers that sit at odd positions? A function that checks whether a vector contains a certain number? Whether all numbers are
+// smaller than some threshold? Be creative!
+
+//@ [index](main.html) | [previous](part09.html) | [raw source](https://www.ralfj.de/git/rust-101.git/blob_plain/HEAD:/workspace/src/part10.rs) | [next](part11.html)