Skip to content

String::pop

String methods · Strings

Level: reference · for working programmers

One line: Removes and returns the last char, or None if empty — the only removal method that is O(1) and cannot panic.

pub fn pop(&mut self) -> Option<char>

Stable since 1.0.0.

It removes a whole character, not a byte: popping from "café" gives 'é' and shortens the string by 2. Because it works from the end, it can find the character boundary by scanning backwards a few bytes, so it is O(1) whatever the string's length.

None on an empty string, which makes while let Some(c) = s.pop() a clean drain-from-the-back loop.

The capacity is unchanged — popping frees no memory. shrink_to_fit does that.

There is no pop_front: removing from the front shifts everything, so it is remove(0) and O(n).

Example

string_pop.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.

fn main() {
    let mut s = String::from("café");
    println!("{:?} len {}", s, s.len());
    println!("popped {:?}", s.pop());
    println!("{:?} len {}", s, s.len());

    // Empty gives None, so this loop terminates on its own.
    let mut word = String::from("abc");
    while let Some(c) = word.pop() {
        println!("popped {c:?}, left {word:?}");
    }
    println!("{:?}", word.pop());

    // Capacity is not returned.
    let mut big = String::with_capacity(32);
    big.push_str("hello");
    big.pop();
    println!("len {} capacity {}", big.len(), big.capacity());

    // Reversing by popping.
    let mut src = String::from("héllo");
    let mut out = String::new();
    while let Some(c) = src.pop() { out.push(c); }
    println!("{out:?}");
}

Verified output of string_pop.rs — regenerated by tools/run_examples.py, never hand-typed.

"café" len 5
popped Some('é')
"caf" len 3
popped 'c', left "ab"
popped 'b', left "a"
popped 'a', left ""
None
len 4 capacity 32
"olléh"

See also

String::pop in the standard library ↗

Po polsku

Spośród metod odejmujących treść ta jedna nigdy nie panikuje i nigdy nie kosztuje więcej niż O(1): pop zdejmuje z końca cały znak (char), a nie bajt, więc "café" skraca się z 5 bajtów do 3 i oddaje Some('é') — polskie "jeż" straci na tym dwa bajty, nie jeden. Dlaczego akurat od końca jest tanio: granicę znaku w UTF-8 da się rozpoznać, cofając się o najwyżej kilka bajtów, więc długość łańcucha znaków nie ma tu znaczenia. Od przodu takiej sztuczki nie ma i właśnie dlatego pop_front nie istnieje — jego rolę pełni remove(0) o koszcie O(n), bo cała reszta musi się przesunąć. Zwracana Option<char> daje None na pustym łańcuchu, co czyni z while let Some(c) = s.pop() pętlę zatrzymującą się samoczynnie (w przykładzie opróżnia "abc" i odwraca "héllo" na "olléh"); pojemność pozostaje przy tym nietknięta — len 4 capacity 32 — bo pamięć oddaje dopiero shrink_to_fit.

Szukaj po polsku: usuwanie ostatniego znaku · granica znaku UTF-8 · pętla while let · rust String pop · rust remove first character of String