Shiklo Tools
PDF40
Image20
Calculators & Converters25
Text & Writing13
Developer26
Video14
Audio14
Document14
Data & Spreadsheet12
Web & SEO9
OCR & Scanning5
Archive & File12
Security & Privacy23
Health & Medical29
QR & Barcode5

Rust Vectors

A vector, written Vec, is a list that can grow and shrink while the program runs. If an array is a box with a fixed number of slots, a vector is a backpack you can keep putting things into. Vectors are probably the collection you will use most in Rust.

Creating a vector and adding items

The vec! macro makes a vector with some starting items. Vec::new() makes an empty one. push adds an item to the end:

fn main() {
    let mut shopping = vec!["milk", "bread"];
    shopping.push("eggs");
    shopping.push("rice");
    println!("{:?}", shopping);
    println!("{} items, first is {}", shopping.len(), shopping[0]);
}
Output
["milk", "bread", "eggs", "rice"]
4 items, first is milk

All items in a vector must have the same type. Rust works the type out from the first items: here it is Vec<&str>, a vector of text slices. The part in angle brackets says what kind of item the vector holds.

Removing items

pop takes the last item off. Because the vector might be empty, it gives back an Option: Some(item) or None. remove takes out the item at a position and shifts the rest along:

fn main() {
    let mut stack = vec![1, 2, 3, 4];
    let top = stack.pop();
    println!("Popped {:?}, left {:?}", top, stack);
    let second = stack.remove(1);
    println!("Removed {}, left {:?}", second, stack);
}
Output
Popped Some(4), left [1, 2, 3]
Removed 2, left [1, 3]

Reading safely with get

v[10] on a short vector stops the program. When an index might be out of range, get is the polite way to ask. It gives Some(&item) if the item exists and None if not, and you decide what to do:

fn main() {
    let colours = vec!["red", "green", "blue"];
    for i in [1, 5] {
        match colours.get(i) {
            Some(c) => println!("Position {} is {}", i, c),
            None => println!("There is nothing at position {}", i),
        }
    }
}
Output
Position 1 is green
There is nothing at position 5

Looping, changing and sorting

Loop with for item in &v to read, and for item in &mut v to change each item in place. The * in *n means "the value this reference points at". Vectors also know how to sort themselves:

fn main() {
    let mut prices = vec![40, 15, 99, 23];
    for p in &mut prices {
        *p += 5;
    }
    println!("With delivery: {:?}", prices);
    prices.sort();
    println!("Sorted: {:?}", prices);
    let total: i32 = prices.iter().sum();
    println!("Total: {}", total);
}
Output
With delivery: [45, 20, 104, 28]
Sorted: [20, 28, 45, 104]
Total: 197

Building a vector from input

A very common pattern is to start with Vec::new() and push items as they arrive, for example numbers typed by the user:

use std::io;

fn main() {
    let mut numbers: Vec<i32> = Vec::new();
    println!("Type 3 numbers:");
    for _ in 0..3 {
        let mut line = String::new();
        io::stdin().read_line(&mut line).expect("could not read");
        numbers.push(line.trim().parse().expect("a whole number"));
    }
    println!("You typed {:?}, the biggest is {}", numbers, numbers.iter().max().unwrap());
}
You type
8
42
17
Output
Type 3 numbers:
You typed [8, 42, 17], the biggest is 42

Practice exercises

  1. Make an empty vector of names, push four names, and print them sorted.
  2. Ask for 5 marks, store them in a vector, and print the average.
  3. Use get to safely print the 10th item of a short vector, with a friendly message when it is missing.