RustArena

Step 6 of 6

A first look at Vec: a list that grows

An array's length is fixed when you write the program. Often you don't know it in advance: orders arrive, players join, a file has however many lines it has. For that, Rust has Vec<T>, called a vector: a list of values of one type that can grow and shrink while the program runs. It's the collection you'll use most in Rust. Module 16 covers it in depth; here are the basics.

fn main() {
    let mut queue = vec![101, 102];
    queue.push(103);
    queue.push(104);
    println!("{:?}", queue);
    println!("{} tickets, first is {}", queue.len(), queue[0]);
}
[101, 102, 103, 104]
4 tickets, first is 101

Starting empty

Vec::new() creates an empty vector, ready to be filled in a loop:

fn main() {
    let mut squares = Vec::new();
    for n in 1..=5 {
        squares.push(n * n);
    }
    println!("{:?}", squares);
}
[1, 4, 9, 16, 25]

Rust works out the element type from what you push. If you never push anything, it can't tell, and asks you (error E0282, type annotations needed for `Vec<_>` ). Then write the type: let scores: Vec<i32> = Vec::new();

Array or Vec?

Array [T; N] Vector Vec<T>
Length fixed, part of the type changes at run time
Typical use days of the week, a 3×3 board orders, lines of input, search results
Adding elements impossible push

Under the hood, a vector keeps its elements in a block of memory it can grow (on the heap, which module 09 explains), while an array is stored directly where it's declared.

Looping over a vector

You can loop over the indexes, for i in 0..v.len(), exactly as with arrays. In real code you'll more often see this form:

fn main() {
    let lap_times = vec![62, 58, 60];
    let mut total = 0;
    for t in &lap_times {
        total += t;
    }
    println!("{} laps, total {} s", lap_times.len(), total);
}
3 laps, total 180 s

The & in &lap_times lets the loop look at the elements without using up the vector. Without it, for t in lap_times takes the vector over, and using lap_times after the loop is an error (E0382, borrow of moved value: `lap_times` ). Why that happens is the topic of the next phase: ownership (module 09) and borrowing with & (module 10). For now, loop over &v (or over the indexes) when you still need v afterwards.

Common mistakes

Your task

Start from an empty vector and use a loop with push to collect the multiples of 7 from 7 up to 49. Then print the vector and how many numbers it holds:

[7, 14, 21, 28, 35, 42, 49]
count: 7

Challenge 2

Fill the blanks: create an empty cart, add a price to it, and print how many items it holds. The program should print 2 items: [499, 1250].

Challenge 3

Write evens_up_to(n), which returns a vector of the even numbers from 2 up to and including n. For example evens_up_to(10) returns [2, 4, 6, 8, 10], and evens_up_to(1) returns an empty vector.

Previous: Grids: arrays of arrays