The problem with repeated values
Consider a program that tells a short story about one person:
println!("My name is John and I am 40 years old");
println!("Coding at age 40 is really fun");
println!("My son is named after me, John");
println!("I'd love him to be as cool as me at age 40");
println!("It's so funny when my wife calls John we both respond");
It works. But the name John and the age 40 appear several times each. To make the story about someone named Andy who is 32, you have to find every occurrence of each value and change it by hand:
println!("My name is Andy and I am 32 years old");
println!("Coding at age 32 is really fun");
println!("My son is named after me, Andy");
println!("I'd love him to be as cool as me at age 32");
println!("It's so funny when my wife calls Andy, we both respond");
With five lines that is tedious. With hundreds of lines it is a real danger: miss one 40 and the program contradicts itself, and nothing warns you. The text is still valid, so the compiler is happy.
Store each value once
A variable gives a value a name, so the value is written in one place and used everywhere through its name. Here is the same story with two variables:
let name = "John";
let age = 40;
println!("My name is {} and I am {} years old", name, age);
println!("Coding at age {} is really fun", age);
println!("My son is named after me, {}", name);
println!("I'd love him to be as cool as me at age {}", age);
println!("It's so funny when my wife calls {}, we both respond", name);
Each {} in the format string is a placeholder. println! fills the placeholders from left to right with the arguments after the string, so the first line prints My name is John and I am 40 years old.
Variables also make the code easier to read. A name like age tells the reader what the value means, while a bare 40 in the middle of a sentence leaves them guessing whether it is an age, a count or a price. Neither variable here uses mut, because the program only reads them. Choosing the value once and never changing it afterwards is the default in Rust.
Changing the story
To make the character Andy, aged 32, edit only the two let lines:
let name = "Andy";
let age = 32;
Every println! line stays as it is. Running the program now prints:
My name is Andy and I am 32 years old
Coding at age 32 is really fun
My son is named after me, Andy
I'd love him to be as cool as me at age 32
It's so funny when my wife calls Andy, we both respond
The program has the same length no matter how many times the name is used. The value lives in one place, so there is nothing to forget and nothing that can fall out of sync.
A shorter way to write placeholders
Instead of listing the arguments after the string, Rust lets you write a variable's name inside the braces. This line prints the same text as the one with {} and name:
println!("My son is named after me, {name}");
The lessons mostly use the positional form, {}, and both work. The braces can hold a plain variable name only: for an expression such as age + 1, pass it as an argument after the string.
The exercise
The starting code already has two variables and a line that prints them:
// Create variables here:
let experience: i32 = 5;
let language: &str = "Python";
// Print story here:
println!("I have {} years of experience with {}", experience, language);
The task is to make the story about 13 years of experience with Java, and the println! line must stay untouched. That is the point of the lesson: change what is on the right side of each =, and nothing else.
- Change
experience. Replace5with13. The typei32stays, because 13 is still a whole number. - Change
language. Replace"Python"with"Java". Keep the quotes, since the value is text.
// Create variables here:
let experience: i32 = 13;
let language: &str = "Java";
// Print story here:
println!("I have {} years of experience with {}", experience, language);
The output is I have 13 years of experience with Java.
Mistakes to avoid
- Editing the string in
println!instead of the variable. It might produce the right output once, but it defeats the purpose and breaks the link between the value and the sentence. - Misspelling a variable in the format arguments. Writing
yearswhere the variable is calledexperiencegiveserror[E0425]: cannot find value `years` in this scope. - Counting placeholders wrong. The number of
{}must match the number of arguments after the string, or the program doesn't compile. - Dropping the quotes around text.
let language: &str = Java;asks Rust to look for a variable calledJavarather than the text.
Key takeaways
- A variable stores a value under a name, so you write the value once and use it many times.
- To change a program's data, change the variable's value and leave the code that uses it alone.
- Placeholders in
println!are filled with the arguments in order. - Repeating a value by hand invites mistakes that the compiler can't catch.
