Lesson 2.4 · 9 min
Text: String and &str
Text is the one value Chatterbox cannot live without, and Rust has two kinds of it. One is fixed text written in the code. The other is text that can grow. Knowing which is which ends the most common beginner stumble.
Adds to ChatterboxChatterbox holds a message as text.
Two kinds of text
Every quoted piece of text you have written so far, like "Chatterbox", is a &str (say "string slice"). It is fixed: it is written in your program and it never grows or shrinks. The & in front is a hint that you are looking at text that lives somewhere else. Chapter 4 explains that fully; for now just read it as "fixed text".
The other kind is String. This is text your program owns and can change: add to the end, build up piece by piece, hold something typed by a user. Chatterbox needs this for messages, because a message is not known when you write the code.
$ cargo run
Hello, world!String::from("Hello") copies fixed text into a new String. push_str adds more text on the end, and push adds one character. Because the text changes, the name needs let mut, exactly as in lesson 2.2.
The compiler keeps them apart
The two kinds are different types, so one cannot quietly stand in for the other.
error[E0308]: mismatched types --> src/main.rs:2:28 | 2 | let greeting: String = "Hello"; | ------ ^^^^^^^ expected `String`, found `&str` | | | expected due to this | help: try using a conversion method | 2 | let greeting: String = "Hello".to_string(); | ++++++++++++
"mismatched types": the name was promised to be a String but the value is a &str. The help text suggests .to_string(). Both .to_string() and String::from do the same job: make an owned String from fixed text.
The other direction is free. Anywhere a function wants fixed text, you can hand it a String by writing & in front. That is why the helper functions in this course take &str: they accept both.
Combining text
You have met format!. It builds a new String from pieces and leaves the originals alone, so it is usually the cleanest way to join text.
What does this print? Remember that len() counts bytes, not letters.
564
Reveal the answer
The program prints: 6 The letter e with an accent takes two bytes in UTF-8, the encoding Rust uses for text, so five letters are six bytes. len() reports bytes. Counting letters is a different method, chars().count(), and you will not need it yet.
Chatterbox v0.2, finished
Time to finish version 0.2. The banner and the greeting are now built as values with format!, the greeting grows with push_str, and everything is printed together at the end. Read it top to bottom: names first, then the text, then the output.
$ cargo run
Chatterbox v0.2
Hi Sam! I'm Chatterbox. Ask me anything.
1 messages so far
Budget: 4096 tokens, quiet: falseChatterbox shows who said what. Make labelled return You: followed by the message. Start from the String that is already there and grow it. You don't need to understand fn yet (chapter 3, lesson 4 explains it): just fill in the body.
Chatterbox shows who said what. Make labelled return You: followed by the message. Start from the String that is already there and grow it. You don't need to understand fn yet (chapter 3, lesson 4 explains it): just fill in the body.
Hidden tests (3): empty_message labels_a_message different_messages_differ
This exercise runs real Rust in your browser through the official Rust Playground, so it needs JavaScript.
What you have now
Chapter 2 is done. Chatterbox v0.2 has names, a counter, numbers, a switch and growing text. It still does the same thing every time you run it. In chapter 3 it starts to decide.
Say it out loud, then reveal
What is the difference between a &str and a String?Reveal
How do you turn fixed text into a String?Reveal
What does len() count for text?Reveal
That is lesson 2.4. Tick it off so the course remembers where you are.
Questions people ask
When should I use String and when &str?
Use &str for text you only read, such as function inputs. Use String when you need to own, build or change text.
Why does Rust have two string types?
One is fixed and cheap to pass around; the other owns its characters and can grow. Keeping them as separate types makes it clear which you are holding.
What does the & in &str mean?
It marks a reference: the text is borrowed from somewhere else. Chapter 4 explains borrowing.