Step 1 of 7
Creating and growing a Vec
A vector, written Vec<T>, is a list of values of one type T, stored next to each other on the heap. An array ([i32; 5]) has a length fixed when you compile; a vector grows and shrinks while the program runs. That's what you need whenever the data comes from input, a file or the network, so Vec is the collection you'll use most in Rust.
fn main() {
let mut scores: Vec<u32> = Vec::new();
scores.push(72);
scores.push(95);
scores.push(88);
println!("{:?} (len {})", scores, scores.len());
let primes = vec![2, 3, 5, 7];
let zeros = vec![0; 5];
println!("{:?} {:?}", primes, zeros);
let last = scores.pop();
println!("popped {:?}, left {:?}", last, scores);
println!("empty? {}", scores.is_empty());
}
[72, 95, 88] (len 3)
[2, 3, 5, 7] [0, 0, 0, 0, 0]
popped Some(88), left [72, 95]
empty? false
Piece by piece:
Vec::new()makes an empty vector. It has no elements yet to infer the type from, so we write it:Vec<u32>.pushadds an element at the end. It changes the vector, so the variable must bemut.vec![2, 3, 5, 7]is a macro that builds a vector from a list;vec![0; 5]makes five copies of0.popremoves the last element and returns it inside anOption:Some(88), orNoneif the vector was empty. Rust makes you deal with the empty case instead of handing you garbage.len()counts the elements;is_empty()is the idiomatic way to check for zero (clippy suggests it overlen() == 0).
How a Vec is stored
The vector variable itself is three numbers on the stack: a pointer to a buffer on the heap, the length (how many elements are in use) and the capacity (how many fit before the buffer is full). When a push finds the buffer full, the Vec allocates a bigger one (about twice the size), moves the elements over and frees the old one. Doubling means most pushes are cheap; growing is rare.
Common mistakes
Forgetting
mut:fn main() { let v = Vec::new(); v.push(1); }error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutableAn empty vector the compiler can't figure out. If nothing ever goes into it, Rust can't guess the element type:
fn main() { let v = Vec::new(); println!("{}", v.len()); }error[E0282]: type annotations needed for `Vec<_>`Write
let v: Vec<i32> = Vec::new();.Mixing types.
vec![1, "two"]is amismatched typeserror: every element has the same type.
Your task
A coffee bar keeps orders in a stack (the newest order is made first). Fill in the blanks: the vector's type, the method that adds an order, and the method that takes the newest one off.
Challenge 2
Write a program that reads whole numbers separated by spaces or newlines, stores them in a Vec<i64>, prints read N numbers, and then prints them in reverse order, one per line, by popping them off with while let Some(n) = numbers.pop().
Challenge 3
A shop wants running totals of its daily sales. Write fn running_totals(sales: &[u32]) -> Vec<u32>: element i of the result is the sum of sales[0] to sales[i]. For [5, 10, 3] return [5, 15, 18]; for an empty slice return an empty vector.