Vec: a growable list
A Vec<T> ("vector") is Rust's growable list: every element has the same type T, they sit next to each other on the heap, and the Vec can grow or shrink. It is the collection you will use most, the way Python uses list and Java uses ArrayList. Create one with Vec::new() or the vec! macro.
fn main() {
let mut langs: Vec<String> = Vec::new(); // empty; the type is written out
langs.push(String::from("rust"));
langs.push(String::from("go"));
langs.push(String::from("python"));
let primes = vec![2, 3, 5, 7]; // vec! infers Vec<i32>
let zeros = vec![0; 4]; // four zeros
println!("{:?} len={}", langs, langs.len());
println!("{:?} {:?}", primes, zeros);
println!("first={} last={:?}", primes[0], primes.last());
let popped = langs.pop(); // Option<String>
println!("popped {:?}, left {:?}", popped, langs);
langs.insert(0, String::from("c")); // shifts everything right
langs.remove(1); // shifts everything left
println!("{:?} contains go? {}", langs, langs.contains(&String::from("go")));
}["rust", "go", "python"] len=3
[2, 3, 5, 7] [0, 0, 0, 0]
first=2 last=Some(7)
popped Some("python"), left ["rust", "go"]
["c", "go"] contains go? trueCall langs.pop() three more times and print each result. What does the third one return, and why?
v[i] or v.get(i)?
There are two ways to read element i. v[i] gives you the element directly and panics (crashes the program with a message) if i is out of range. v.get(i) never panics: it returns Option<&T>, Some(&element) or None. Use indexing when an out-of-range index would be a bug in your program; use get when the index comes from outside (user input, a file, another service).
fn main() {
let scores = vec![90, 72, 85];
for i in [1, 5] {
match scores.get(i) {
Some(s) => println!("scores[{i}] = {s}"),
None => println!("no score at {i}"),
}
}
println!("{}", scores.get(9).copied().unwrap_or(0));
}scores[1] = 72
no score at 5
0Runtime panic: index out of bounds
fn main() {
let scores = vec![90, 72, 85];
let i = 3;
println!("{}", scores[i]);
}thread 'main' (13230805) panicked at main.rs:4:26:
index out of bounds: the len is 3 but the index is 3
note: run with `RUST_BACKTRACE=1` environment variable to display a backtraceThe Vec has three elements, at indexes 0, 1 and 2. Rust checks every index at run time; instead of reading whatever memory sits after the Vec (what C would do), it stops the program. This is a panic, not a compile error: the compiler cannot know the value of i in general.
Check the length first, or use scores.get(i) and handle None. The panic message gives the file, line and column, and both the length and the index you asked for, which is usually enough to spot an off-by-one.
fn main() {
let scores = vec![90, 72, 85];
let i = 3;
match scores.get(i) {
Some(s) => println!("{s}"),
None => println!("no score at index {i} (len {})", scores.len()),
}
}push would overflow it, the Vec allocates a bigger block (roughly double), copies the elements over and frees the old block. That makes push cheap on average. If you know the final size, Vec::with_capacity(n) allocates once up front.