Two kinds of rules
Variable names in Rust follow two sets of rules that are easy to confuse. The first are hard rules: break one and the code doesn't compile. The second are conventions: break one and the code still works, but the compiler warns you, and other Rust programmers will find your code harder to read.
The hard rules
A name may contain letters, digits and underscores, and it must not start with a digit. It can't contain spaces or symbols such as # or .. It also can't be a keyword like match or let. Each of these fails to compile:
let 18spam: i32 = 1;
let first name = "Kate";
let #name: bool = true;
let match = 5;
- A name that starts with a number is reported as
expected identifier, found `18spam`, with the help textidentifiers cannot start with a number. - A space ends the name early. In
let first name = "Kate";the compiler stops atnameand complains that it expected one of:,;,=,@or|. - The
#inlet #nameis an error too:expected pattern, found `#`. - A keyword gives
expected identifier, found keyword `match`. The compiler suggestsr#match, a raw identifier, but you are better off choosing another word.
The convention: snake_case
When a name has several words, Rust code writes them in lowercase and separates them with underscores. This style is called snake_case:
let company_name = "Apple";
let founding_year = 1976;
let is_unicorn = true;
let number_of_employees = 137000;
Writing the same name in camelCase, with capital letters between words, is accepted by the compiler but warned about:
let firstName = "Jane";
println!("{}", firstName);
The program compiles and runs, but the compiler prints warning: variable `firstName` should have a snake case name and suggests first_name. The warning comes from the non_snake_case check.
Other kinds of Rust names use other styles. Constants are written in SCREAMING_SNAKE_CASE, and types in CamelCase. Variables and functions always use snake_case.
Names are case-sensitive
Uppercase and lowercase letters make different names, so these are three separate variables:
let name = "Kate";
let Name = "Andy";
let NAME = "George";
println!("{} {} {}", name, Name, NAME); // Output: Kate Andy George
It compiles, and the output is Kate Andy George. But Name and NAME each trigger the snake-case warning, and telling variables apart by case alone is confusing. Pick names that differ in more than their capitals.
Choose names that explain themselves
Rust accepts any valid name, so the choice is yours. Compare:
let a = 25;
let b = 13;
let c = a * b;
println!("{}", c);
with:
let hours = 25;
let rate = 13;
let pay = hours * rate;
println!("{}", pay);
Both print 325. The second tells the reader what the numbers mean. Short names like x and y are fine for small, obvious uses, but anything that matters deserves a descriptive name. A name that starts a yes/no question, like is_employed or has_account, signals a bool.
A name that begins with an underscore, like _unused, tells the compiler you declared the variable on purpose without using it, so it skips the unused-variable warning.
Be consistent
Don't mix styles in one program. A pair like first_name and lastName forces the reader to remember which style each name uses, and the compiler warns about the second one anyway. Warnings don't stop the build, which is exactly why they are easy to ignore. Treat them as the compiler pointing at something you will want to fix, and keep the output clean so that a new, real warning stands out.
Solving the exercise
You declare three variables with let, using snake_case for each:
first_nameholds"John". The two words are joined by an underscore, because a space isn't allowed.is_employedholdstrue. Theis_prefix makes it read as a question that has a yes or no answer.years_of_experienceholds5. Four words, all lowercase, joined with underscores.
let first_name = "John";
let is_employed = true;
let years_of_experience = 5;
None of the variables needs mut, since they are never changed. Printing them with println!("{} {} {}", first_name, is_employed, years_of_experience) gives John true 5.
Key takeaways
- Names use letters, digits and underscores, can't start with a digit, can't contain spaces or symbols, and can't be keywords.
- Rust variables use snake_case. camelCase compiles but produces a
non_snake_casewarning. - Names are case-sensitive, but don't rely on case alone to tell variables apart.
- A descriptive name is worth the extra typing.
