Rust Strings
Text handling is one of the first places Rust feels different from other languages, mostly because it actually has two string types. Once you know why, it stops being confusing.
&str vs String
Section titled “&str vs String”&str(“string slice”) — text that already exists somewhere, usually written directly in your code. Fixed size, can’t grow.String— an owned, growable piece of text. You can add to it, and it lives on the heap.
fn main() { let literal: &str = "hello"; // a string slice let owned: String = String::from("hello"); // an owned String
println!("{literal} / {owned}");}A simple rule of thumb: if you’re just printing fixed text, "like this" (a &str) is fine. If you need to build, grow, or modify text at runtime, reach for String.
Growing a String
Section titled “Growing a String”fn main() { let mut greeting = String::from("Hello"); greeting.push_str(", World"); // add a &str greeting.push('!'); // add a single char
println!("{greeting}");}Output:
Hello, World!Combining strings
Section titled “Combining strings”You can join strings with +, or use format! (which is usually the clearer option):
fn main() { let first = String::from("Hello, "); let second = String::from("World!");
let combined = first + &second; // note the & before second println!("{combined}");
// format! is often easier to read: let name = "Ferris"; let greeting = format!("Hello, {name}!"); println!("{greeting}");}Useful string methods
Section titled “Useful string methods”A handful you’ll use constantly:
fn main() { let text = " Hello, Rust! ";
println!("{}", text.trim()); // "Hello, Rust!" (no padding) println!("{}", text.to_uppercase()); // " HELLO, RUST! " println!("{}", text.to_lowercase()); // " hello, rust! " println!("{}", text.contains("Rust")); // true println!("{}", text.trim().len()); // 12 (length in bytes) println!("{}", text.trim().replace("Rust", "World")); // "Hello, World!"}Looping over a string
Section titled “Looping over a string”To go character by character, use .chars():
fn main() { for c in "abc".chars() { println!("{c}"); }}Practice
Section titled “Practice”1. Clean up messy input
Section titled “1. Clean up messy input”Someone typed " rUsT is FUN " into a form. Turn it into rust is great: remove the extra spaces, make it all lowercase, and replace fun with great. Then print the result and its length. Hint: string methods can be chained, one after another: text.trim().to_lowercase()....
Show solution
fn main() { let input = " rUsT is FUN ";
// trim first, then lowercase, then replace "fun" (now lowercase) let clean = input.trim().to_lowercase().replace("fun", "great");
println!("{clean}"); println!("{} bytes", clean.len());}Output:
rust is great13 bytesThe order matters: if you called .replace("fun", "great") before .to_lowercase(), nothing would be replaced, because the text still says FUN.
2. Build an email address
Section titled “2. Build an email address”Given first = "Ada" and last = "Lovelace", build the String ada.lovelace@example.com and print it. Then print whether it contains an @. Hint: format! can take expressions like first.to_lowercase() as arguments for its {} slots.
Show solution
fn main() { let first = "Ada"; let last = "Lovelace";
let email = format!("{}.{}@example.com", first.to_lowercase(), last.to_lowercase());
println!("{email}"); println!("looks valid: {}", email.contains('@'));}Output:
ada.lovelace@example.comlooks valid: true&stris borrowed, fixed text;Stringis owned and can grow.- Grow a
Stringwith.push_str()(for text) or.push()(for a single character). - Prefer
format!over+when combining strings — it’s clearer and doesn’t move anything. - Common methods:
.trim(),.to_uppercase(),.contains(),.replace(),.chars().
Quick check
Section titled “Quick check”Quick check
1. Which string type is owned and can grow at runtime?
2. Why does this page prefer format! over + when combining more than one or two strings?
3. Why can't you index a Rust string like text[0]?
4. Which method adds a single character to a growing String, like greeting.push('!')?
Score: 0 / 4
Read more
Section titled “Read more”- Storing UTF-8 Encoded Text with Strings — The Rust Book: the official chapter on
String, including why you can’t index by position. - String Slices — The Rust Book: what a
&strreally is, once you’ve learned about borrowing. - Strings — Rust by Example: runnable examples of
Stringand&str, plus escape characters and raw strings. String— standard library docs: every method on an ownedString, each with a small example.str— standard library docs: methods liketrim,contains,replaceandsplitthat work on any text.