I am working on rustling's iterators5.rs and I came to see this solution for this function:
fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize {
// map is a hashmap with String keys and Progress values.
// map = { "variables1": Complete, "from_str": None, ... }
// map.values().filter(|x| **x == value).count()
map.values().filter(|x| x == &value).count()
}
As far as I understand it seems like map.values()
is returning an iterator of references according to the documentation.
"An iterator visiting all values in arbitrary order. The iterator element type is &'a V." See: https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.values
However, I am not sure why if I do map.values().filter(|x|)
, Rust Analyzer recognizes x
as a type &&Progress
?
Is it because in .filter()
and hence its closure, only takes in references of the values from the upstream chain? Therefore map.values() produces &x
and .filter() only takes on references hence &&x
.
I tried finding the documentation but I'm not sure where it says this: https://doc.rust-lang.org/core/iter/trait.Iterator.html#method.filter
Edit: Follow up question
Thanks for the comments for pointing out that &Self::Item
means that the filter function is taking on a reference from the iterator.
My follow up question would be that since
x
in map.values().filter(|x|)
is of &&Progress
type, why does &x
make it a &Progress
type? Is this some kind of double dereferencing?
And why does x in x == &value
of (|&x: &Progress| x == &value)
become &Progress
?
I would have expected x
to be still &&Progress