Iterator collect explicit type annotation

I'm new to Rust.
Reading the doc, the iterator collect method returns a generic type.
But I don't understand why we must explicitly give a type annotation :
let foo = vec![1, 2, 3].into_iter().map(|x| x * 2).collect::<Vec<_>>();
the compiler knows that foo is of type Vec.
but this line give an error, and I expect an error :
let foo = vec![1, 2, 3].into_iter().map(|x| x * 2).collect::<Vec<String>>();

The compiler knows the input type for collect but not the output type.

You can do:

fn main() {
    let foo = vec![1, 2, 3].into_iter().map(|x| x * 2).collect::<Vec<_>>();
    let bar = vec![1, 2, 3].into_iter().map(|x| x * 2).collect::<Box<[_]>>();
}

(Playground)

In the second case, bar will be a Box<[i32]> instead of a Vec<i32>.

2 Likes

The iterator implies the item type, so the compiler knows that the iterator produces integers. What the compiler doesn't know is what kind of collection you want to put those items into. You can't only collect into a vector! You can collect into a HashSet, VecDeque or a BTreeSet, or any other type that implements FromIterator.

It is the type of the resulting collection that you have to specify. The fact that the item type is known doesn't matter – you have to specify the collection type, because that is not implied, as it can arbitrarily be chosen by the caller and it's not determined by anything else in the code.

4 Likes

thank you. It's more clear now.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.