I recently encountered a problem while learning about iterators. I attempted to convert a list of numbers into a Vec, but when I changed the type to HashMap, no error occurred. For example:
type Test = Vec<(usize, Vec<usize>)>;
// type TestHashMap = HashMap<usize, Vec<usize>>;
...
fn make_heavy_things() -> Test {
let x = (1..=10).map(|v| (v, vec![v])).collect();
x
}
// x can be a HashMap or Vec depending on the return type
Both types seem to work without any issues, and common methods like len() work as expected. I'm curious about the reason behind this behavior.
A range can not be collected to a hashmap, a hashmap needs pairs of key and value, which a range is not, your iterator is not a range it's a range mapped to a pair of
(usize, Vec<usize>).Iterator::collectis a generic operation, it can collect into anything implementing theFromIteratortrait, which is the case ofVecandHashMapIFF the iterator returns pairs (2-uples) and the first element of the pair implementsHash + Eq.This provides a type-safe one-stop-shop for converting iterators to various forms, and allows for useful compositions, for instance you can collect iterators of
Resultinto a singleResult, which will stop at the firstResult::Errit encounters and return that, and will otherwise collect into whatevet concrete collection you specifyWhy is it a problem?