Program Life Cycle

The lifecycle of a Rust program involves several stages from writing the code to running the executable. Here’s a breakdown of each phase:

Before we go to the detailed steps, we must have a full view of components needed for a Rust program:

Preparation

Writing the code

  1. To start a new Rust program, run a command

The main entry point file generated by this command is main.rs

cargo new <app_name>
  1. Or if you build a library, you run a command

Modules and Crates: Code is organized into modules and crates (libraries or binaries). Rust has an ecosystem of reusable libraries (crates) that can be imported to extend functionality.

The main entry point file generated by this command is lib.rs

cargo new --lib <app_name>
  1. Package management file

Cargo.toml and Cargo.lock is the two files that manage the dependencies of the Rust program. To understand how to use these files correctly, follow this guide: https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html

  1. Understand basic syntax

Here's a quick overview of Rust's basic syntax with examples to help you get started:

  • Variables and Mutability: Variables are immutable by default, meaning you can't change their values unless explicitly marked with mut.

fn main() {
    let x = 5;        // Immutable variable
    let mut y = 10;   // Mutable variable
    y += 5;
    println!("x: {}, y: {}", x, y);
}
  • Data types: We already learnt about data types in the last lesson. Please revise if you forget.

  • Functions: Functions are defined with the fn keyword, and parameters need types.

fn main() {
    greet("Alice");
    let result = add(5, 3);
    println!("Sum: {}", result);
}

fn greet(name: &str) {
    println!("Hello, {}!", name);
}

fn add(a: i32, b: i32) -> i32 {
    a + b   // No semicolon means this is the return value
}
  • Conditionals: if, else if, and else for conditional logic.

fn main() {
    let number = 7;
    if number < 5 {
        println!("Less than 5");
    } else if number == 5 {
        println!("Equal to 5");
    } else {
        println!("Greater than 5");
    }
}
  • Loops: Rust has several looping constructs: loop, while, and for.

fn main() {
    let mut count = 0;

    // Infinite loop
    loop {
        if count >= 3 {
            break;
        }
        println!("Count: {}", count);
        count += 1;
    }

    // While loop
    while count < 5 {
        println!("Count: {}", count);
        count += 1;
    }

    // For loop
    for i in 0..5 {
        println!("i: {}", i);
    }
}

Those are basic syntax that you must know before diving into harder concetps.

Compilation

To compile and run the Rust program, run the command:

cargo run
  • Rust’s rustc compiler translates the source code into machine code in a single pass, focusing on safety and performance.

  • The compilation process includes:

    • Parsing: Rust parses the code to check for syntax correctness.

    • Analysis and Borrow Checker: Rust’s borrow checker enforces memory safety rules by validating ownership, borrowing, and lifetime rules, ensuring memory safety without a garbage collector.

    • Code Generation and Optimization: Rust generates optimized machine code, removing unused variables, inlining functions, and applying other optimizations.

  • Result: Rust produces an intermediate binary in the form of an object file, then links these files to produce an executable file.

Exercises

Last updated