Strings and Text Processing

push() and push_str()

The .push() and .push_str() methods append a single Unicode character (char) or a string slice (&str) onto the end of a mutable String in amortized $O(1)$ time.

Signatures and Behavior

impl String {
    pub fn push(&mut self, ch: char);
    pub fn push_str(&mut self, string: &str);
}
Method Parameter Appends Amortized Complexity
s.push(ch) char (by value) 1..=4 UTF-8 bytes encoding ch $O(1)$
s.push_str(slice) &str (borrowed) slice.len() UTF-8 bytes $O(k)$ where $k = \text{slice.len()}$

Because push_str borrows its argument as &str, the source string is not consumed and remains usable after the call:

fn main() {
    let mut message = String::from("Status");
    let suffix = "OK";

    message.push(':');      // Appends 1-byte ASCII char
    message.push(' ');
    message.push_str(suffix); // Appends &str; `suffix` remains valid
    message.push(' ');
    message.push('✓');      // Appends 3-byte Unicode char (U+2713)

    println!("{message} (suffix='{suffix}', total bytes={})", message.len());
}
Status: OK ✓ (suffix='OK', total bytes=14)

Appending via the += Operator (AddAssign<&str>) and Extend

String also implements:

  • AddAssign<&str> (s += "more" ), which delegates directly to s.push_str("more").
  • Extend<char> and Extend<&str>, allowing you to append an entire iterator of characters or string slices onto an existing String via .extend(...):
fn main() {
    let mut path = String::from("/usr");
    path += "/local"; // Calls push_str("/local")

    let segments = ["/bin", "/rustc"];
    path.extend(segments);

    println!("Full path: {path}");
}
Full path: /usr/local/bin/rustc