5.1 Keywords

Keywords are predefined, reserved words with special meanings in the Rust language. They form the building blocks of syntax and cannot be used as identifiers (like variable or function names) unless escaped using the raw identifier syntax (r#keyword). Many Rust keywords overlap with C/C++, but Rust adds several unique ones to support features like ownership, borrowing, pattern matching, and concurrency.

5.1.1 Raw Identifiers

Occasionally, you might need to use an identifier that conflicts with a Rust keyword. This often happens when interfacing with C libraries or using older Rust code (crates) written before a word became a keyword in a newer Rust edition.

To resolve this, Rust provides raw identifiers: prefix the identifier with r#. This tells the compiler to treat the following word strictly as an identifier, ignoring its keyword status.

For example, if a C library exports a function named try (a reserved keyword in Rust), you would call it as r#try() in your Rust code. Similarly, if Rust introduces a new keyword like gen (as in the 2024 edition) that was used as a function or variable name in an older crate you depend on, you can use r#gen to refer to the item from the old crate.

fn main() {
    // 'match' is a keyword, used for pattern matching.
    // To use it as a variable name, we need `r#`.
    let r#match = "Keyword used as identifier";
    println!("{}", r#match);

    // 'type' is also a keyword.
    struct Example {
        r#type: i32, // Use raw identifier for field name
    }
    let instance = Example { r#type: 1 };
    println!("Field value: {}", instance.r#type);

    // 'example' is NOT a keyword. Using r# is allowed but unnecessary.
    // Both 'example' and 'r#example' refer to the same identifier.
    let example = 5;
    let r#example = 10; // This shadows the previous 'example'.
    println!("Example: {}", example); // Prints 10

    // Note: Inside format strings like println!, use the identifier *without* r#.
    // println!("{}", r#match); // This would be a compile error.
}

While you can use r# with non-keywords, it’s generally only needed for actual keyword conflicts or, rarely, for future-proofing if you suspect an identifier might become a keyword later.

5.1.2 Keyword Categories

Rust classifies keywords into three groups:

  1. Strict Keywords: Actively used by the language and always reserved.
  2. Reserved Keywords: Reserved for potential future language features; currently unused but cannot be identifiers.
  3. Weak Keywords: Have special meaning only in specific syntactic contexts; can be used as identifiers elsewhere.

5.1.3 Strict Keywords

These keywords have defined meanings and cannot be used as identifiers without r#.

KeywordDescriptionC/C++ Equivalent (Approximate)
asType casting, renaming imports (use path::item as new_name;)(type)value, static_cast
asyncMarks a function or block as asynchronousC++20 co_await context
awaitPauses execution until an async operation completesC++20 co_await
breakExits a loop or block prematurelybreak
constDeclares compile-time constantsconst
continueSkips the current loop iterationcontinue
crateRefers to the current crate rootNone
dynUsed with trait objects for dynamic dispatchVirtual functions (indirectly)
elseThe alternative branch for an if or if let expressionelse
enumDeclares an enumeration (sum type)enum
externLinks to external code (FFI), specifies ABIextern "C"
falseBoolean literal falsefalse (C++), 0 (C)
fnDeclares a functionFunction definition syntax
forLoops over an iteratorfor, range-based for (C++)
genReserved (Rust 2024+, experimental generators)C++20 coroutines
ifConditional expressionif
implImplements methods or traits for a typeClass methods (C++), None (C)
inPart of for loop syntax (for item in iterator)Range-based for (C++)
letIntroduces a variable declarationDeclaration syntax (no direct keyword)
loopCreates an unconditional, infinite loopwhile(1), for(;;)
matchPattern matching expressionswitch (less powerful)
modDeclares a moduleNamespaces (C++), None (C)
moveForces capture-by-value in closuresLambda captures (C++)
mutMarks a variable or reference as mutableNo direct C equivalent (const is inverse)
pubMakes an item public (visible outside its module)public: (C++ classes)
refBinds by reference within a pattern& in patterns (C++)
returnReturns a value from a function earlyreturn
SelfRefers to the implementing type within impl or trait blocksCurrent class type (C++)
selfRefers to the instance in methods (&self, &mut self, self)this pointer (C++)
staticDefines static items (global lifetime) or static lifetimesstatic
structDeclares a structure (product type)struct
superRefers to the parent module.. in paths (conceptual)
traitDeclares a trait (shared interface/behavior)Abstract base class (C++), Interface (conceptual)
trueBoolean literal truetrue (C++), non-zero (C)
typeDefines a type alias or associated type in traitstypedef, using (C++)
unsafeMarks a block or function with relaxed safety checksC code is implicitly unsafe
useImports items into the current scope#include, using namespace
whereSpecifies constraints on generic typesrequires (C++20 Concepts)
whileLoops based on a conditionwhile

5.1.4 Reserved Keywords (For Future Use)

These are currently unused but reserved for potential future syntax. Avoid using them as identifiers.

Reserved KeywordPotential Use AreaC/C++ Equivalent (Possible)
abstractAbstract types/methodsvirtual ... = 0; (C++)
becomeTail calls?None
boxCustom heap pointersstd::unique_ptr (concept)
dodo-while loop?do
finalPrevent overridingfinal (C++)
macroAlternative macro system?#define (concept)
overrideExplicit method overrideoverride (C++)
privPrivate visibility?private: (C++)
tryError handling syntaxtry (C++)
typeofType introspection?typeof (GNU C), decltype (C++)
unsizedDynamically sized typesNone
virtualVirtual dispatchvirtual (C++)
yieldGenerators/coroutinesco_yield (C++20)

5.1.5 Weak Keywords

These words have special meaning only in specific contexts. Outside these contexts, they can be used as identifiers without r#.

  • union: Special meaning when defining a union {} type, otherwise usable as an identifier.
  • 'static: Special meaning as a specific lifetime annotation, otherwise usable (though rare due to the leading ').
  • Contextual Keywords (Examples): Words like default can have meaning within specific impl blocks but might be usable elsewhere. macro_rules is primarily seen as the introducer for declarative macros.

5.1.6 Comparison with C/C++

While C programmers will recognize keywords like if, else, while, for, struct, enum, const, and static, Rust introduces many new ones. Keywords like let, mut, match, mod, crate, use, impl, trait, async, await, and unsafe reflect Rust’s different approaches to variable declaration, mutability control, pattern matching, modularity, interfaces, asynchronous programming, and safety boundaries. The ownership system itself doesn’t have dedicated keywords but relies on how let, mut, fn signatures, and lifetimes interact.