Strings
Rust is a systems programming language focused on speed, memory safety, and fearless concurrency — and its text handling is built on UTF-8 with two complementary types: the owned String and the borrowed &str .
Learn Strings in our free Rust course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Rust course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll create and grow strings, concatenate and format them, use common methods, and understand why .len() counts bytes.
What You'll Learn in This Lesson
1️⃣ Creating and Growing Strings
There are two string types to know. A &str is a borrowed slice (string literals are &str ), while a String is owned and growable. You build a String with String::from or .to_string() , then grow it with push_str and push .
Note that .len() reported 10 bytes . For this ASCII text that equals the character count, but for accented letters or emoji it would not — strings are UTF-8.
2️⃣ Concatenation, Formatting, and Methods
You can join strings with + (which moves the left side and borrows the right), but the more flexible tool is format! , which builds a String without moving anything. Strings also come with a rich set of methods: trim , to_uppercase , contains , replace , and more.
Because you can't index a string by position, you iterate with .chars() to walk characters safely. This respects UTF-8 boundaries automatically.
Your turn. Fill in the blanks marked ___ , then run it.
Count words and characters and uppercase a sentence. Run it with cargo run .
📋 Quick Reference — Strings
Practice quiz
What is the difference between String and &str?
- No difference
- &str is owned; String is borrowed
- String is owned and growable; &str is a borrowed slice
- String is on the stack
Answer: String is owned and growable; &str is a borrowed slice. String owns growable heap data; &str is a borrowed, fixed view.
What type is a string literal like "hello"?
- &str
- String
- char
- Vec<u8>
Answer: &str. String literals have type &str (specifically &'static str).
Which method appends a &str to a String?
- push
- add_str
- concat
- push_str
Answer: push_str. push_str appends a string slice; push appends a single char.
What does String::len() return?
- The number of characters
- The number of bytes
- The capacity
- The number of words
Answer: The number of bytes. len() returns the byte length, since strings are UTF-8.
Why can't you index a string with s[0]?
- UTF-8 bytes may not align to characters
- It is too slow
- Strings are immutable
- Indexing is unsafe
Answer: UTF-8 bytes may not align to characters. A byte index could land mid-character in UTF-8, so direct indexing is disallowed.
What does "foo" + &String::from("bar") via let c = a + &b produce?
- foo bar
- barfoo
- foobar
- an error
Answer: foobar. + concatenates, moving the left String and borrowing the right, giving foobar.
Which is the cleanest way to build a String from several pieces without moving them?
- The + operator
- format!
- push
- to_string
Answer: format!. format! borrows its arguments and returns a new String.
How do you iterate over characters safely?
- .bytes()
- .len()
.chars() walks Unicode characters respecting UTF-8 boundaries.
What does "rust".to_uppercase() return?
- rust
- RUST
- Rust
- an error
Answer: RUST. to_uppercase returns RUST.
What does "the quick brown fox".split_whitespace().count() return?
- 3
- 19
- 4
- 1
Answer: 4. There are 4 whitespace-separated words.