Reputation: 23134
Here is an example from Rust by Example:
fn is_odd(n: u32) -> bool {
n % 2 == 1
}
fn main() {
println!("Find the sum of all the squared odd numbers under 1000");
let upper = 1000;
// Functional approach
let sum_of_squared_odd_numbers: u32 =
(0..).map(|n| n * n) // All natural numbers squared
.take_while(|&n| n < upper) // Below upper limit
.filter(|n| is_odd(*n)) // That are odd
.fold(0, |sum, i| sum + i); // Sum them
println!("functional style: {}", sum_of_squared_odd_numbers);
}
Why does the closure for take_while
take its argument by reference, while all the others take by value?
Upvotes: 5
Views: 1111
Reputation: 431489
The implementation of Iterator::take_while
is quite illuminating:
fn next(&mut self) -> Option<I::Item> {
if self.flag {
None
} else {
self.iter.next().and_then(|x| {
if (self.predicate)(&x) {
Some(x)
} else {
self.flag = true;
None
}
})
}
}
If the value returned from the underlying iterator were directly passed to the predicate, then ownership of the value would also be transferred. After the predicate was called, there would no longer be a value to return from the TakeWhile
adapter if the predicate were true!
Upvotes: 4