100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Rust

The String Type in Rust

Rust's owned, growable, heap-allocated String type versus the borrowed &str string slice, and how to build and combine them.

Ownership & BorrowingBeginner9 min readJul 8, 2026
Analogies

Introduction

Rust has two main string types that work together: String, an owned, growable, heap-allocated buffer of UTF-8 text, and &str, a borrowed string slice that is often a view into a String or a string literal baked into the binary. Understanding when to use each, and how ownership and borrowing apply to them, is essential for writing idiomatic Rust code.

🏏

Cricket analogy: String is like a team owning a permanent, growable squad roster they can add players to; &str is like a broadcaster's read-only reference to that same roster during a live telecast, or to a printed matchday program that never changes.

Syntax

rust
let s1 = String::from("hello");
let s2: String = "world".to_string();
let s3: &str = "a string literal"; // borrowed, 'static lifetime

let combined = s1 + " " + &s2;      // + operator (consumes s1)
let combined2 = format!("{} {}", s2, s3); // format! (borrows both)

Explanation

String::from("hello") and "hello".to_string() both allocate a new String on the heap that you own outright and can grow with methods like push_str and push. A &str, by contrast, is just a reference - a pointer and a length - into some UTF-8 bytes that live elsewhere, whether that's a String, a string literal compiled into the binary (which has a 'static lifetime), or a slice of either. Concatenation with the + operator calls a method that takes ownership of the left-hand String (moving it) and borrows the right-hand &str, so the left operand can't be used afterward; format! is often preferred for combining multiple strings because it only borrows its arguments and leaves them usable.

🏏

Cricket analogy: String::from and push_str building an owned, growable buffer is like a scorer's official book you can keep adding overs to; the + operator taking ownership of the left String is like handing over your scorebook entirely, so format! is preferred when you just want to borrow both team's figures side by side without giving either up.

Example

rust
fn greet(name: &str) -> String {
    format!("Hello, {}!", name)
}

fn main() {
    let owned = String::from("Rustacean");
    let literal = "World";

    // greet accepts both String (via &owned) and a literal directly
    println!("{}", greet(&owned));
    println!("{}", greet(literal));

    let mut s = String::new();
    s.push_str("Hi");
    s.push('!');
    println!("{}", s);
}

Output

text
Hello, Rustacean!
Hello, World!
Hi!

Key Takeaways

  • String is owned, heap-allocated, and growable; &str is a borrowed, immutable view into UTF-8 text.
  • String::from("...") and "...".to_string() both create a new owned String.
  • The + operator moves the left-hand String and borrows the right-hand &str.
  • format! combines strings by borrowing its arguments, leaving them usable afterward.
  • String literals have type &'static str because they are embedded directly in the compiled binary.

Practice what you learned

Was this page helpful?

Topics covered

#Rust#RustProgrammingStudyNotes#Programming#TheStringTypeInRust#String#Type#Syntax#Explanation#StudyNotes#SkillVeris