The everyday list type in Rust is Vec — a growable array that owns its elements. The quickest way to build one is the vec! macro, and because Vec has no plain {} formatting, you print the whole thing with the debug placeholder {:?}:
let nums = vec![10, 20, 30];
println!("{:?}", nums); // prints [10, 20, 30]
You could process a list with an index loop like for i in 0..nums.len() — it compiles, but it's not how Rust is written. Idiomatic code uses iterators: .iter() borrows each element in turn (the vector stays alive and usable afterwards), and you chain adapters onto it. .map(|x| ...) transforms every element, .filter(|x| ...) keeps only the ones that pass a test, .sum() reduces everything to one number, and .collect() gathers results into a new Vec:
let doubled: Vec<i32> = nums.iter().map(|x| x * 2).collect();
The trap:
.collect() can build many different containers — a Vec, a HashSet, even a String — so the compiler must be told which one you want. Every beginner eventually leaves the annotation off, and compilation stops with this exact error:
error[E0283]: type annotations needed
--> src/main.rs:3:9
|
3 | let squares = nums.iter().map(|x| x * x).collect();
| ^^^^^^^ ------- type must be known at this point
|
= note: cannot satisfy `_: FromIterator<i32>`
help: consider giving `squares` an explicit type
|
3 | let squares: Vec<_> = nums.iter().map(|x| x * x).collect();
| ++++++++
The help: line hands you the fix: annotate the binding, e.g. let squares: Vec<i32> = .... The same rule applies to .sum() — write let sum: i32 = ... so it knows which number type to produce.
Two closure details worth knowing:
Because .iter() only borrows, the closure in filter receives a reference — write *x to dereference it before doing arithmetic like *x % 2 == 0. And when you want the kept values as owned numbers rather than references, add .cloned() before .collect(): it copies each surviving &i32 into a plain i32.
Assignment
Follow the Coding Tutorial to process one list three ways, without a single index variable:
- Build
numsas the vector[1, 2, 3, 4, 5]with thevec!macro. - Use
.iter().map(...).collect()to buildsquares, and print it with{:?}. - Use
.iter().sum()to computesum, and print it. - Use
.iter().filter(...).cloned().collect()to buildevens, and print it with{:?}.
The exact expected output is:
squares = [1, 4, 9, 16, 25]
sum = 15
evens = [2, 4]
Hint
If the compiler says type annotations needed, give the binding an explicit type: : Vec<i32> for a collect, : i32 for a sum. If it complains inside the filter closure, remember the element arrives as a reference — dereference it with *x.
Free plan: 30 tutor messages. Premium is unlimited.