← Back to Rust Course | Chapter 9: Collections | Lesson 1 of 6

Vec Basics

A Vec is a list that can grow or shrink as you add or remove things from it.
Syntax
rust
let mut name: Vec<Type> = Vec::new();
let name = vec![v1, v2, v3];
name.push(value);
name[index]
name.get(index)

Creating a Vec

A Vec is created either with Vec::new() for an empty list or the vec! macro to list initial elements directly.

Example: Creating a Vec

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `numbers`, set to `vec![1, 2, 3]`
    let numbers = vec![1, 2, 3];
    // Print "{:?}" to the console, substituting in `numbers` (with a trailing newline)
    println!("{:?}", numbers);
}

Pushing and Popping

.push() appends an element to the end of a mutable Vec, and .pop() removes and returns the last element, wrapped in an Option since the vector could be empty.

Example: Pushing and Popping

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare a mutable variable `stack`, initialized to `Vec::new()`
    let mut stack = Vec::new();
    // Append `10` to `stack`
    stack.push(10);
    // Append `20` to `stack`
    stack.push(20);
    // Declare an immutable variable `last`, set to `stack.pop()`
    let last = stack.pop();
    // Print "Popped: {:?}, remaining: {:?}" to the console, substituting in `last, stack` (with a trailing newline)
    println!("Popped: {:?}, remaining: {:?}", last, stack);
}

Accessing Elements Safely

Direct indexing with [] panics if the index is out of bounds. .get(index) instead returns an Option, letting you handle a missing index without crashing.

Example: Accessing Elements Safely

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `items`, set to `vec!["a", "b", "c"]`
    let items = vec!["a", "b", "c"];
    // Print "{:?}" to the console, substituting in `items.get(1)` (with a trailing newline)
    println!("{:?}", items.get(1));
    // Print "{:?}" to the console, substituting in `items.get(10)` (with a trailing newline)
    println!("{:?}", items.get(10));
}

Iterating Over a Vec

A for loop can iterate directly over a Vec's elements by reference, letting you process each item without taking ownership of the whole vector.

Example: Iterating Over a Vec

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `scores`, set to `vec![90, 85, 77]`
    let scores = vec![90, 85, 77];
    // Loop over `&scores`, binding each item to `score`
    for score in &scores {
        // Print "Score: {}" to the console, substituting in `score` (with a trailing newline)
        println!("Score: {}", score);
    }
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Trying to index past the end of a Vec, which panics at runtime instead of returning a default value.
  2. Forgetting Vec::new() needs mut on the binding before you can push new elements onto it.
  3. Using vec[i] when the index might be out of bounds, instead of the safer .get(i) which returns an Option.
Chapter Summary
  • Vec<T> is a growable, heap-allocated list of elements of type T.
  • vec![...] is a convenient macro for creating a Vec with initial elements.
  • .push() adds an element to the end; .pop() removes and returns the last one.
  • Indexing with [] panics on an out-of-bounds index, while .get() returns Option safely.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.