---
title: "1.8 Keywords and naming identifiers"
description: "Rust's reserved keywords, the rules for identifiers, and the snake_case naming conventions the compiler itself nudges you toward."
url: "https://learnrust.net/chapter-1/keywords-and-identifiers/"
last_updated: "2026-06-11"
---

# 1.8 Keywords and naming identifiers

Every name in your program (variables so far; functions and types soon) is an **identifier**, and this lesson covers what identifiers may look like, plus the short list of words you can't have because Rust got there first.

## Keywords

A **keyword** is a word with reserved meaning in the language. You've used six already: `fn`, `let`, `mut`, `use`, and the value-words `true` and `false` (coming in chapter 4). The 2024 edition reserves these:

```
as       async    await    break    const    continue crate
dyn      else     enum     extern   false    fn       for
if       impl     in       let      loop     match    mod
move     mut      pub      ref      return   self     Self
static   struct   super    trait    true     type     unsafe
use      where    while
```

(Plus the lone underscore `_`, which acts as a special "deliberately unnamed" marker you've already brushed against in `_unused`.) Don't memorize the table; you'll absorb it by collision. A keyword can't be an identifier, and the compiler is blunt about it:

```rust
fn main() {
    let fn = 5;
    println!("{fn}");
}
```

```
error: expected identifier, found keyword `fn`
 --> src/main.rs:2:9
  |
2 |     let fn = 5;
  |         ^^ expected identifier, found keyword
```

> **For advanced readers**
>
> A second tier of words (`abstract`, `become`, `box`, `do`, `final`, `gen`, `macro`, `override`, `priv`, `try`, `typeof`, `unsized`, `virtual`, `yield`) is *reserved for the future*: unusable today, not yet meaning anything. This is editions machinery from lesson [0.12](https://learnrust.net/chapter-0/rust-editions/) working as designed, parking words now so claiming them later breaks nothing. And if you ever must use a keyword as a name (say, a field called `type` in data from elsewhere), raw identifier syntax `r#type` exists. File under "good to know it exists."

## The rules

The hard rules for identifiers are short: letters, digits, and underscores only; it can't *start* with a digit; and it can't be a keyword. Identifiers are case-sensitive, so `score`, `Score`, and `SCORE` are three different names (defining all three is legal, and a misdemeanor).

## The conventions

The rules leave room for chaos, so the community settled conventions, and here Rust does something unusual: the compiler itself nudges you. Variables and functions are written in **snake_case**: lowercase words joined by underscores. Type names (chapter 10) get `UpperCamelCase`, and constants (lesson 5.1) get `SCREAMING_SNAKE_CASE`. Stray from the pattern and you get a warning:

```rust
fn main() {
    let playerName = "Ada";
    println!("{playerName}");
}
```

```
warning: variable `playerName` should have a snake case name
 --> src/main.rs:2:9
  |
2 |     let playerName = "Ada";
  |         ^^^^^^^^^^ help: convert the identifier to snake case: `player_name`
  |
  = note: `#[warn(non_snake_case)]` (part of `#[warn(nonstandard_style)]`) on by default
```

The program runs, but the message is clear, and so is the ecosystem's expectation: all Rust code everywhere uses these conventions, which is why code you find online always *looks* like the code in this course. (Veterans of other languages' brace-and-case wars will recognize what a gift that is.)

Beyond case, good names are a judgment call, and the judgment improves with a few principles. Make the length of a name proportional to its importance: a loop counter alive for two lines can be `i`; a value used across a whole function deserves a word; something central to the program deserves a good one. Name the *thing*, not the type (`elapsed_seconds` beats `the_number`). And don't abbreviate to save four keystrokes that cost every future reader a guess.

A field guide, in the spirit of an old learncpp.com table:

| Declaration | Verdict |
|---|---|
| `let elapsed_seconds = 4;` | conventional |
| `let s = 4;` | fine in a two-line scrap, cryptic anywhere else |
| `let elapsedSeconds = 4;` | works, but the compiler will tut (snake case, please) |
| `let ELAPSED = 4;` | shouting is for constants (lesson 5.1) |
| `let _elapsed = 4;` | the underscore says "unused on purpose," so only when it is |
| `let seconds_elapsed_since_the_program_started_running = 4;` | technically legal, like a 40-character password |
| `let 2fast = 4;` | illegal: starts with a digit |
| `let player name = 4;` | illegal: spaces can't appear in identifiers |

> **Best practice**
>
> Name things in `snake_case`, descriptively, as if the reader knows nothing. The three seconds you spend choosing `remaining_attempts` over `ra` are repaid every single time anyone (including you) reads the line.

## Quiz time

**Question #1**

Judge each: conventional, legal-but-unconventional, or illegal?

a) `let user_count = 10;`
b) `let UserCount = 10;`
c) `let 3d_points = 10;`
d) `let match = 10;`
e) `let x = 10;` (as a program's central value, used in 30 places)

<details class="solution">
<summary>Show solution</summary>

a) Conventional.
b) Legal but unconventional for a variable; that casing belongs to types, and the compiler warns.
c) Illegal: identifiers can't start with a digit.
d) Illegal: `match` is a keyword.
e) Legal and conventionally *shaped*, but a bad name for something used 30 times; one-letter names are for tiny scopes.

</details>

**Question #2**

Predict what the compiler says about this program (it does compile):

```rust
fn main() {
    let finalScore = 95;
    println!("{finalScore}");
}
```

<details class="solution">
<summary>Show solution</summary>

A `non_snake_case` warning: variable `finalScore` should have a snake case name, with the help line suggesting `final_score`. The program still compiles and prints 95.

</details>

Names sorted. Next, a quick lesson on the space *between* the names, and the tool that ends every argument about it.

## Sitemap

See the full [sitemap](https://learnrust.net/sitemap.md) for all pages.
