The following code is an example solution of one Exercism exercise:
use std::collections::HashMap;
pub fn can_construct_note(magazine: &[&str], note: &[&str]) -> bool {
let magazine_words = magazine.iter().fold(HashMap::new(), |mut words, str| {
*words.entry(str).or_insert(0) += 1;
words
});
let note_words = note.iter().fold(HashMap::new(), |mut words, str| {
*words.entry(str).or_insert(0) += 1;
words
});
note_words
.iter()
// why???
.all(&|(w, count)| magazine_words.get(w).unwrap_or(&0) >= count)
}
First question, as the title suggests, what's the point of doing that? Since we're going to consume the closure only once anyway in this case. Is that a Rust convention or idiom that I missed?
Second question, why is this code valid? Since Iterator::all() takes F as second argument, not &F. Iterator in std::iter - Rust
A type parameter F means "any type". It does not exclude reference types. Rust doesn't really treat any types specially in the context of generics (which is the whole point of generics). Types can be primitives, structs, enums, references, arrays, raw pointers, etc., whatever satisfies the declared trait bounds.
Regarding why, I suspect that this particular instance is a typo: maybe they intended to use & inside the closure args to perform some more advanced "pattern-match destructuring"?
That being said, out there in the wild, there can be instances where prefixing a closure with &mut (or &) can be useful, when dealing with a dyn Fn… API (polymorphic not through generics, but through dynamic dispatch (~"dynamic types")):
/// A function such as this one will often be written as:
/// `fn example (mut f: impl FnMut())` instead, but if this function
/// were a trait method instead, then in order for that trait
/// to be `dyn`-safe, `impl` / generics would not be available,
/// making this `&mut dyn` API mandatory.
fn example (f: &mut dyn FnMut())
{
f();
}
// To call `example`:
example(&mut || {
// …
});