1.10Introduction to literals and operators
You've been using literals and operators since lesson 1.1; this lesson introduces them properly, so the vocabulary stops being implicit.
Literals
A literal is a value written directly in the source code: the 5 in let x = 5;, the "Hello, world!" in your first program. A literal is its value, fixed forever, which is the difference between it and a variable: 5 can never be six, while a variable named x holds whatever was last put in its box.
You've met number literals (5), decimal literals (6.7), string literals ("Hello"), character literals ('H'), and the keywords true and false are literals too (chapter 4 gives them their type). One nicety for big numbers: underscores can be sprinkled into numeric literals as digit separators, and the compiler ignores them entirely.
fn main() {
let population = 1_000_000;
println!("{population}");
}1000000
1_000_000 and 1000000 are the same literal; one of them can be read aloud on the first try. (Integer literals can also be written in hex, octal, and binary forms; lesson 4.3 covers those.)
Operators
An operator combines or transforms values: +, -, *, /, the = of assignment, the == of comparison. The values an operator acts on are its operands, and the result is a new value, which is how operations chain: in 1 + 2 + 3, the first + produces 3, which becomes an operand of the second.
The number of operands an operator takes is its arity (rhymes with charity, mostly used by people writing language courses). Most operators are binary, two operands: 6 * 4. A few are unary, one operand: the minus in -5 negates. C and C++ have a famous ternary operator taking three; Rust deleted it, because if can do its job directly, a trick lesson 4.7 will show off.
When operators chain, they apply in the order your math teacher promised: multiplication before addition, parentheses to override.
fn main() {
println!("{}", 2 + 3 * 4);
println!("{}", (2 + 3) * 4);
}14
20
The full precedence rules arrive in chapter 6, along with the only advice about them worth memorizing (when in doubt, parenthesize).
Warning
If you know another C-family language, your fingers know x++ and x-- for adding or subtracting one. Rust doesn't have them. Write what you mean:
count += 1; // add one (compound assignment, lesson 6.3)
count -= 1; // subtract one
This was a deliberate deletion, not an oversight. In C, the increment operators came in two flavors (++x and x++) whose difference inside larger expressions bred a whole literature of interview questions and a steady supply of bugs, up to and including undefined behavior. Rust's designers concluded the two saved characters weren't paying their way. It won't be the last time you see that judgment call: where a feature's main output was trick questions, Rust tended to leave it out.
One related habit to not import from elsewhere: assignment in Rust isn't a value you can chain or test, so a = b = 5 doesn't do what a C programmer hopes. (What an assignment does produce is a small piece of the next lesson's story.)
Quiz time
Question #1
In let total = price * 3;, identify every literal, operator, and operand.
Show solution
3 is a literal. * is a (binary) operator, and its operands are price and 3. The = is part of the let initialization syntax giving total its first value. (price and total are identifiers naming variables.)
Question #2
What does this print?
fn main() {
let x = 2;
println!("{}", -x + 10 * 2);
}Show solution
18
Unary minus makes -2, multiplication goes first (10 * 2 = 20), then -2 + 20 = 18.
Question #3
A friend's code contains attempts++;. What happens when they compile it, and what should it say instead?
Show solution
It won't compile; Rust has no ++ operator. The fix is attempts += 1; (or the long form attempts = attempts + 1;).
You now know the words for what you've been typing. The next lesson is the one this chapter has been building toward: the difference between an expression and a statement, which sounds like grammar trivia and turns out to be the key to how Rust thinks.