Start learning free

LESSON 107 OF 414 · ARRAYS I

Removing the Last Item of a Vec in Rust: pop()

Lesson Read the full explanation

Another way to change the data in a vector is with the .pop() method, which removes the last element from a vector:

let mut three_arr = vec![1, 4, 6];

// Remove last element:
three_arr.pop();

// three_arr is now vec![1, 4]

// Remove last element again:
three_arr.pop();

// three_arr is now vec![1]

Assignment
Follow the Coding Tutorial and let's play with some arrays.


Hint
Look at the examples above if you get stuck.


STEP 1 OF 2
    Ctrl + Enter to check

    RUST · ARRAYS I

    Array Pop in Rust, explained

    What pop does

    The pop method removes the last element of a Vec and shortens it by one. It is the counterpart of push: one adds at the end, the other takes from the end. Both are cheap, because no other element has to move.

    let mut three_arr = vec![1, 4, 6];
    
    three_arr.pop();
    println!("{:?}", three_arr);
    
    three_arr.pop();
    println!("{:?}", three_arr);
    [1, 4]
    [1]

    Each call removes whatever is last at that moment, so calling it twice in a row removes the last two elements, in order from the end.

    The return value

    Unlike methods that only change the vector, pop also gives you the element it removed. Because the vector might be empty, the result is an Option: Some(value) when there was a last element, and None when there wasn't.

    let mut ages = vec![14, 32, 50, 21];
    let popped = ages.pop();
    println!("{:?} {:?}", popped, ages);
    
    let mut empty: Vec<i32> = Vec::new();
    println!("{:?}", empty.pop());
    Some(21) [14, 32, 50]
    None

    Popping an empty vector is not an error. It does nothing and returns None. That makes pop safer than indexing the last element by hand, since v[v.len() - 1] would fail on an empty vector.

    Using or ignoring the result

    When you only want the element gone, as in this lesson, just call pop() as a statement and ignore the result. When you want the value, you have several choices:

    • if let Some(x) = v.pop() runs a block only when there was an element.
    • v.pop().unwrap() gives the plain value but panics on an empty vector, so use it only when you know the vector isn't empty.
    • v.pop().unwrap_or(0) supplies a fallback for the empty case.

    Popping in a loop

    Because pop returns None at the end, it combines well with while let to empty a vector from the back, which is how a stack is usually processed:

    let mut st = vec![1, 2, 3];
    while let Some(top) = st.pop() {
        print!("{} ", top);
    }
    println!();
    3 2 1 

    The loop stops by itself when the vector is empty. Last in, first out is exactly this behaviour.

    Gotchas in Rust

    The vector must be mut

    Removing an element changes the vector, so the binding needs let mut. Without it, the compiler reports that it cannot borrow the vector as mutable.

    Only the last element

    pop takes no argument and never removes from the front or the middle. For other positions, other methods exist, such as remove(index), which shifts everything after the index.

    Indexes shift at the end

    After a pop, the length is one smaller, so the old last index no longer exists. If a vector had four elements and you pop once, reading index 3 now panics because only indexes 0 to 2 remain. Recompute positions from len() after changing the vector.

    The lesson's exercise

    The starter code gives two mutable vectors, fruits with three strings and ages with four numbers. The exercise has two steps.

    1. Remove the last fruit. One call to fruits.pop() removes "grapefruit". The result is ignored, because the lesson only needs the vector to change.
    2. Remove the last two ages. Call ages.pop() twice, on two lines. The first call removes 21 and the second removes 50.
    let mut fruits = vec!["mango", "kiwi", "grapefruit"];
    let mut ages = vec![14, 32, 50, 21];
    
    fruits.pop();
    ages.pop();
    ages.pop();

    Afterwards fruits is ["mango", "kiwi"] and ages is [14, 32].

    Key takeaways

    • v.pop() removes the last element and returns it as Some(value), or None if the vector was empty.
    • The vector must be declared with let mut.
    • Ignoring the result is fine when you only want the element removed.
    • while let Some(x) = v.pop() processes a vector from the back until it is empty.
    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free