Skip to content

Rust Basic Syntax

Overview

This chapter delves deeply into Rust's basic syntax, including variables, constants, scope, naming conventions, and other core concepts. Mastering these fundamentals is a prerequisite for writing high-quality Rust code.

📝 Variable Declaration

Immutable Variables (Default)

rust
fn immutable_variables() {
    // Immutable by default
    let x = 5;
    println!("Value of x: {}", x);

    // x = 6; // Compilation error! Cannot modify immutable variable

    // Type annotations
    let y: i32 = 10;
    let z: f64 = 3.14;
    println!("y: {}, z: {}", y, z);

    // Delayed initialization
    let a;
    a = 42; // Must initialize before use
    println!("a: {}", a);

    // Unused variable (suppress warning)
    let _unused = "This variable will not be used";
}

Mutable Variables

rust
fn mutable_variables() {
    // Mutable variable
    let mut x = 5;
    println!("Initial value of x: {}", x);

    x = 6; // Can modify
    println!("New value of x: {}", x);

    // Type cannot change
    let mut number = 10;
    number = 20; // OK
    // number = "hello"; // Compilation error! Type mismatch

    // Mutability propagation
    let mut vec = vec![1, 2, 3];
    vec.push(4); // Can modify content
    println!("Vector: {:?}", vec);
}

Variable Shadowing

rust
fn variable_shadowing() {
    let x = 5;

    // Shadow previous x
    let x = x + 1;
    println!("Shadowed x: {}", x); // 6

    // Shadow in new scope
    {
        let x = x * 2;
        println!("Inner scope x: {}", x); // 12
    }

    println!("Outer scope x: {}", x); // 6

    // Shadowing can change type
    let spaces = "   ";
    let spaces = spaces.len(); // Now it's a numeric type
    println!("Number of spaces: {}", spaces);

    // Comparison: Mutable variables cannot change type
    let mut guess = "42";
    // guess = guess.len(); // Compilation error!
}

🏷️ Constants

Constant Definition

rust
// Global constants
const MAX_POINTS: u32 = 100_000;
const PI: f64 = 3.14159265359;
const APP_NAME: &str = "My Application";

fn constants_example() {
    // Function-level constant
    const LOCAL_CONST: i32 = 42;

    println!("Max points: {}", MAX_POINTS);
    println!("Pi: {}", PI);
    println!("App name: {}", APP_NAME);
    println!("Local constant: {}", LOCAL_CONST);

    // Constant expressions
    const SECONDS_IN_MINUTE: u32 = 60;
    const SECONDS_IN_HOUR: u32 = SECONDS_IN_MINUTE * 60;
    const SECONDS_IN_DAY: u32 = SECONDS_IN_HOUR * 24;

    println!("Seconds in a day: {}", SECONDS_IN_DAY);
}

Constants vs Immutable Variables

rust
fn const_vs_immutable() {
    // Constant: Value must be known at compile time
    const COMPILE_TIME: i32 = 42;

    // Immutable variable: Value determined at runtime
    let runtime_value = get_runtime_value();

    println!("Compile-time constant: {}", COMPILE_TIME);
    println!("Runtime value: {}", runtime_value);
}

fn get_runtime_value() -> i32 {
    use std::time::{SystemTime, UNIX_EPOCH};
    let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
    now.as_secs() as i32 % 100
}

🎯 Scope and Lifetime

Scope Basics

rust
fn scope_basics() {
    let outer = "Outer variable";

    { // New scope starts
        let inner = "Inner variable";
        println!("Inner can access: {}, {}", outer, inner);

        // Shadow outer variable
        let outer = "Shadowed outer variable";
        println!("After shadowing: {}", outer);
    } // inner is destroyed here

    println!("Outer scope: {}", outer); // Original value restored
    // println!("{}", inner); // Compilation error! inner not in scope
}

Ownership Scope

rust
fn ownership_scope() {
    {
        let s = String::from("hello"); // s enters scope
        println!("s: {}", s);
    } // s leaves scope, memory is freed

    // println!("{}", s); // Compilation error! s not in scope

    let s1 = String::from("world");
    let s2 = s1; // Ownership of s1 moves to s2

    // println!("{}", s1); // Compilation error! s1 is invalid
    println!("s2: {}", s2);
}

📏 Identifiers and Naming Conventions

Naming Rules

rust
// Valid identifiers
fn naming_conventions() {
    // Snake case (recommended)
    let user_name = "Alice";
    let max_count = 100;
    let is_valid = true;

    // Unicode support
    let 变量名 = "Chinese variable name";
    let переменная = "Russian variable name";

    // Underscore prefix (usually for unused variables)
    let _unused_var = 42;
    let __internal_var = "Internal variable";

    // Numbers (cannot start with a number)
    let var1 = "Variable1";
    let var_2 = "Variable2";
    // let 1var = "Error"; // Compilation error!

    println!("{}, {}, {}", user_name, max_count, is_valid);
    println!("{}, {}", 变量名, переменная);
}

Rust Naming Conventions

rust
// Constants: Uppercase + underscores
const MAX_SIZE: usize = 1024;
const DEFAULT_TIMEOUT: u64 = 30;

// Structs, enums, traits: Pascal case
struct UserAccount {
    user_id: u64,
    account_type: AccountType,
}

enum AccountType {
    Basic,
    Premium,
    Enterprise,
}

trait Drawable {
    fn draw(&self);
}

// Functions, variables: Snake case
fn calculate_total_price(base_price: f64, tax_rate: f64) -> f64 {
    base_price * (1.0 + tax_rate)
}

// Modules: Snake case
mod user_management {
    pub fn create_user() {}
    pub fn delete_user() {}
}

// Macros: Snake case
macro_rules! debug_print {
    ($x:expr) => {
        println!("Debug: {:?}", $x);
    };
}

🔤 Literals

Numeric Literals

rust
fn numeric_literals() {
    // Integer literals
    let decimal = 98_222;        // Decimal (underscore separated)
    let hex = 0xff;              // Hexadecimal
    let octal = 0o77;            // Octal
    let binary = 0b1111_0000;    // Binary
    let byte = b'A';             // Byte (u8 type)

    println!("Numeric literals: {}, {}, {}, {}, {}",
             decimal, hex, octal, binary, byte);

    // Floating-point literals
    let float1 = 2.0;
    let float2 = 3.14159;
    let scientific = 1e6;       // Scientific notation
    let scientific2 = 2.5e-4;

    println!("Floating-point literals: {}, {}, {}, {}",
             float1, float2, scientific, scientific2);

    // Type suffixes
    let x = 42u32;      // u32 type
    let y = 3.14f32;    // f32 type
    let z = 100_i64;    // i64 type

    println!("Type suffixes: {}, {}, {}", x, y, z);
}

Character and String Literals

rust
fn string_literals() {
    // Character literals
    let c1 = 'a';
    let c2 = '中';
    let c3 = '😀';
    let c4 = '\n';       // Escape character
    let c5 = '\x41';     // ASCII code
    let c6 = '\u{1F600}'; // Unicode

    println!("Characters: {}, {}, {}", c1, c2, c3);

    // String literals
    let s1 = "Hello, World!";
    let s2 = "Contains\nnewline";
    let s3 = "Contains\"quotes\"";
    let s4 = r"Raw string\nnot escaped";
    let s5 = r#"Raw string with "quotes""#;

    println!("String: {}", s1);
    println!("Newline: {}", s2);
    println!("Quotes: {}", s3);
    println!("Raw: {}", s4);
    println!("Raw quotes: {}", s5);

    // Multiline string
    let multiline = "This is a\
                     multiline string\
                     continuing here";

    let multiline_raw = r"
        This is a raw
        multiline string
        keeping original format
    ";

    println!("Multiline: {}", multiline);
    println!("Raw multiline: {}", multiline_raw);
}

Boolean and Unit Literals

rust
fn boolean_and_unit() {
    // Boolean literals
    let t = true;
    let f = false;

    println!("Boolean values: {}, {}", t, f);

    // Unit type
    let unit = ();
    println!("Unit type: {:?}", unit);

    // Unit type function
    let result = print_hello();
    println!("Function returns: {:?}", result);
}

fn print_hello() -> () {
    println!("Hello!");
    // Implicitly returns ()
}

🎭 Expressions and Statements

Statements vs Expressions

rust
fn statements_vs_expressions() {
    // Statement: Performs an operation but does not return a value
    let x = 5; // let statement

    // Expression: Evaluates and returns a result
    let y = {
        let x = 3;
        x + 1 // Expression, note no semicolon
    };

    println!("y: {}", y); // 4

    // Function call is an expression
    let result = add_one(5);
    println!("Result: {}", result);

    // if is an expression
    let condition = true;
    let number = if condition { 5 } else { 6 };
    println!("Conditional value: {}", number);

    // Block is an expression
    let block_result = {
        let a = 1;
        let b = 2;
        a + b // Return value
    };
    println!("Block result: {}", block_result);
}

fn add_one(x: i32) -> i32 {
    x + 1 // Expression
}

Complex Expressions

rust
fn complex_expressions() {
    // Nested expressions
    let result = {
        let base = 10;
        let multiplier = {
            let a = 2;
            let b = 3;
            a * b
        };
        base * multiplier
    };
    println!("Nested expression result: {}", result);

    // Conditional expression chain
    let number = 6;
    let description = if number % 4 == 0 {
        "Divisible by 4"
    } else if number % 3 == 0 {
        "Divisible by 3"
    } else if number % 2 == 0 {
        "Divisible by 2"
    } else {
        "Odd"
    };
    println!("{} {}", number, description);

    // Match expression
    let coin = Coin::Quarter;
    let value = match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter => 25,
    };
    println!("Coin value: {}", value);
}

#[derive(Debug)]
enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter,
}

🏃‍♂️ Control Flow Syntax

Conditional Expressions

rust
fn conditional_syntax() {
    let number = 7;

    // Basic if
    if number < 5 {
        println!("Less than 5");
    }

    // if-else
    if number % 2 == 0 {
        println!("Even");
    } else {
        println!("Odd");
    }

    // if-else if-else
    if number < 0 {
        println!("Negative");
    } else if number > 0 {
        println!("Positive");
    } else {
        println!("Zero");
    }

    // Complex conditions
    let age = 18;
    let has_license = true;
    let has_car = false;

    if age >= 18 && has_license && has_car {
        println!("Can drive alone");
    } else if age >= 18 && has_license {
        println!("Can borrow a car");
    } else if age >= 16 {
        println!("Can learn to drive");
    } else {
        println!("Too young");
    }
}

Loop Syntax

rust
fn loop_syntax() {
    // Infinite loop
    let mut counter = 0;
    let result = loop {
        counter += 1;
        if counter == 10 {
            break counter * 2; // Return value
        }
    };
    println!("Loop result: {}", result);

    // Labeled loop
    'outer: loop {
        println!("Enter outer loop");

        'inner: loop {
            println!("Enter inner loop");
            break 'outer; // Break out of outer loop
        }

        println!("This line won't execute");
    }

    // while loop
    let mut number = 3;
    while number != 0 {
        println!("Countdown: {}", number);
        number -= 1;
    }

    // for loop
    let a = [10, 20, 30, 40, 50];

    // Iterate over array
    for element in a.iter() {
        println!("Value: {}", element);
    }

    // Iterate over range
    for number in (1..4).rev() {
        println!("Reverse: {}", number);
    }

    // Iterate with index
    for (i, value) in a.iter().enumerate() {
        println!("Index {}: Value {}", i, value);
    }
}

📝 Chapter Summary

Through this chapter, you should have mastered:

Basic Syntax

  • ✅ Variable declaration (mutable vs immutable)
  • ✅ Constant definition and usage
  • ✅ Variable shadowing and scope
  • ✅ Rust naming conventions

Literals and Expressions

  • ✅ Various literal notations for different types
  • ✅ Difference between expressions and statements
  • ✅ Constructing complex expressions
  • ✅ Conditional and loop syntax

Best Practices

  1. Follow Rust naming conventions
  2. Use mutability appropriately
  3. Leverage scope to manage lifetime
  4. Prefer expressions over statements

Continue Learning: Next Chapter - Rust Data Types

Content is for learning and research only.