sync titles
[rust-101.git] / src / part10.rs
index e0481a89120ef41e045f420d915666df7f6bd30d..53110dc0d335e390631fdfafbb3b98b0cd73d411 100644 (file)
@@ -1,8 +1,7 @@
 // Rust-101, Part 10: Closures
 // ===========================
 
 // Rust-101, Part 10: Closures
 // ===========================
 
-use std::io::prelude::*;
-use std::{fmt,io};
+use std::fmt;
 use part05::BigInt;
 
 //@ Assume we want to write a function that does *something* on, say, every digit of a `BigInt`.
 use part05::BigInt;
 
 //@ Assume we want to write a function that does *something* on, say, every digit of a `BigInt`.
@@ -24,7 +23,7 @@ impl BigInt {
         //@ Remember that the `mut` above is just an annotation to Rust, telling it that we're okay with `a` being mutated.
         //@ Calling `do_action` on `a` takes a mutable borrow, so mutation could indeed happen.
         for digit in self {
         //@ Remember that the `mut` above is just an annotation to Rust, telling it that we're okay with `a` being mutated.
         //@ Calling `do_action` on `a` takes a mutable borrow, so mutation could indeed happen.
         for digit in self {
-            a.do_action(digit);
+            a.do_action(digit);                                     /*@*/
         }
     }
 }
         }
     }
 }
@@ -40,7 +39,7 @@ impl Action for PrintWithString {
     // Here we perform performs the actual printing of the prefix and the digit. We're not making use of our ability to
     // change `self` here, but we could replace the prefix if we wanted.
     fn do_action(&mut self, digit: u64) {
     // Here we perform performs the actual printing of the prefix and the digit. We're not making use of our ability to
     // change `self` here, but we could replace the prefix if we wanted.
     fn do_action(&mut self, digit: u64) {
-        println!("{}{}", self.prefix, digit);
+        println!("{}{}", self.prefix, digit);                       /*@*/
     }
 }
 
     }
 }
 
@@ -73,7 +72,7 @@ impl BigInt {
     fn act<A: FnMut(u64)>(&self, mut a: A) {
         for digit in self {
             // We can call closures as if they were functions - but really, what's happening here is translated to essentially what we wrote above, in `act_v1`.
     fn act<A: FnMut(u64)>(&self, mut a: A) {
         for digit in self {
             // We can call closures as if they were functions - but really, what's happening here is translated to essentially what we wrote above, in `act_v1`.
-            a(digit);
+            a(digit);                                               /*@*/
         }
     }
 }
         }
     }
 }
@@ -115,7 +114,7 @@ fn inc_print_even(v: &Vec<i32>, offset: i32, threshold: i32) {
     //@ 
     //@ 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.
     //@ 
     //@ 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) {
+    for i in v.iter().map(|n| *n + offset).filter(|n| *n > threshold) {
         println!("{}", i);
     }
 }
         println!("{}", i);
     }
 }
@@ -132,8 +131,9 @@ fn print_enumerated<T: fmt::Display>(v: &Vec<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
 // 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`](http://doc.rust-lang.org/stable/std/iter/trait.FromIterator.html).
-    v.iter().filter(|n| *n % divisor == 0).collect()
+    //@ [`FromIterator`](http://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`](http://doc.rust-lang.org/stable/std/iter/trait.Iterator.html) to learn about more functions
 }
 
 // **Exercise 10.1**: Look up the [documentation of `Iterator`](http://doc.rust-lang.org/stable/std/iter/trait.Iterator.html) to learn about more functions
@@ -141,4 +141,4 @@ fn filter_vec_by_divisor(v: &Vec<i32>, divisor: i32) -> Vec<i32> {
 // 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!
 
 // 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](part08.html) | [next](main.html)
+//@ [index](main.html) | [previous](part09.html) | [next](part11.html)