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
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
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
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
1. Which type is owned and heap-allocated?
2. What happens to the left-hand operand when using the + operator to concatenate two strings?
3. Why is format! often preferred over + for combining multiple strings?
4. What is the lifetime of a string literal like "hello"?
5. Which two calls both produce an owned String from a &str?
Was this page helpful?
You May Also Like
Slices in Rust
Slices are references to a contiguous sequence of elements within a collection, letting you view data without owning it.
Ownership in Rust
Rust's core memory-safety system where every value has exactly one owner and is dropped when that owner goes out of scope.
Borrowing and References in Rust
How Rust lets code access data without taking ownership, using immutable and mutable references checked by the borrow checker.
Vectors in Rust
A Vec<T> is a growable, heap-allocated list that lets you store a variable number of values of the same type.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics