Introduction to Rust

Get Rust installed, compile your first program, and learn how Cargo organises a project.

What is Rust?

Rust is a systems programming language that compiles to fast native code, prevents segfaults, and guarantees thread safety. Mozilla started it in 2010. It gives you memory safety without a garbage collector.

Key Features

  • Memory Safety: No null pointers, no dangling pointers, no data races
  • Zero-Cost Abstractions: High-level features with no runtime overhead
  • Concurrency: Write concurrent code without data races
  • Performance: Comparable to C and C++, 10 to 100 times faster than Python
  • Tooling: Cargo (package manager), rustfmt (formatter), clippy (linter)
  • Helpful Compiler: Error messages that teach you

Coming from Python?

If you write Python, Rust will feel different but pay off:

  • No GIL: True parallelism across CPU cores
  • Compiled: Binary deployment, no Python runtime needed
  • Static typing: Catch bugs at compile time instead of runtime
  • No garbage collector: Deterministic memory management via ownership
  • 10 to 100 times faster: Performance comparable to C/C++

For a side-by-side comparison, see Chapter 0: Python to Rust.

Where Rust Shines

Use CaseWhy Rust?
CLI ToolsSingle binary, fast startup, cross-platform
Web ServicesHigh performance, safe concurrency
System ProgrammingOS kernels, drivers, embedded systems
WebAssemblySafe, fast code in the browser
Game DevelopmentPerformance + safety guarantees
BlockchainSecurity-critical applications

Installation

Linux and macOS

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Windows

Download and run rustup-init.exe

Verify Installation

rustc --version
cargo --version

You should see output like:

rustc 1.93.0 (254b59607 2026-01-19)
cargo 1.93.0 (083ac5135 2025-12-15)

Update Rust

rustup update

Your First Rust Program

# Create a new project
cargo new hello_world
cd hello_world

# Your project structure
# hello_world/
# ├── Cargo.toml    (project configuration)
# └── src/
#     └── main.rs   (your code)

Look at src/main.rs:

fn main() {
    println!("Hello, world!");
}

Run it:

cargo run

Output:

   Compiling hello_world v0.1.0 (/path/to/hello_world)
    Finished dev [unoptimized + debuginfo] target(s) in 0.50s
     Running `target/debug/hello_world`
Hello, world!

Manual Compilation (Without Cargo)

# Create a file
echo 'fn main() { println!("Hello!"); }' > hello.rs

# Compile
rustc hello.rs

# Run
./hello

Understanding the Basic Program

fn main() {
    println!("Hello, world!");
}

Reading it piece by piece:

ElementExplanation
fnKeyword to define a function
mainSpecial function, the entry point of every Rust program
()Parameters (none here)
{}Function body
println!A macro (note the !) that prints to console
"Hello, world!"A string literal
;Statement terminator

Macros vs Functions

  • println! with ! is a macro (generates code at compile time)
  • println without ! would be a function (but doesn't exist)

Common macros:

  • println!(): Print with newline
  • print!(): Print without newline
  • format!(): Create a String
  • vec![]: Create a vector
  • panic!(): Terminate program with error

Cargo Basics

Cargo Commands

# Create new project (binary)
cargo new myproject

# Create new library
cargo new --lib mylib

# Build (debug mode)
cargo build

# Build (release mode - optimized)
cargo build --release

# Run the program
cargo run

# Run with arguments
cargo run -- arg1 arg2

# Check code without building (fast)
cargo check

# Run tests
cargo test

# Update dependencies
cargo update

# Format code
cargo fmt

# Lint code
cargo clippy

Project Structure

myproject/
├── Cargo.toml          # Project manifest
├── Cargo.lock          # Dependency lock file (generated)
├── src/
│   └── main.rs         # Entry point
└── target/             # Build artifacts (generated)
    └── debug/
        └── myproject   # Your executable

Cargo.toml

The project configuration file:

[package]
name = "myproject"
version = "0.1.0"
edition = "2024"  # Rust 1.85+ supports the 2024 edition

[dependencies]
# Add external crates here
# serde = "1.0"

Note on editions: Rust uses an "edition" system to introduce changes while keeping backward compatibility. The 2024 edition is the latest (stabilised in Rust 1.85). All code in this tutorial works with both 2021 and 2024 editions. If you see edition = "2021" in examples, that's still valid. Use whichever edition you prefer.

Hello World Variations

With Variables

fn main() {
    let name = "Rustacean";
    println!("Hello, {}!", name);
}

With User Input

use std::io;

fn main() {
    println!("What's your name?");
    
    let mut name = String::new();
    io::stdin()
        .read_line(&mut name)
        .expect("Failed to read line");
    
    println!("Hello, {}!", name.trim());
}

Run it:

cargo run
# Enter your name when prompted

With Command Line Arguments

use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    
    if args.len() > 1 {
        println!("Hello, {}!", args[1]);
    } else {
        println!("Hello, world!");
    }
}

Run it:

cargo run -- Alice
# Output: Hello, Alice!

The Rust Compiler as Teacher

The compiler is your friend. Try this:

fn main() {
    let x = 5;
    x = 6;  // Error!
    println!("{}", x);
}

The compiler says:

error[E0384]: cannot assign twice to immutable variable `x`
 --> src/main.rs:3:5
  |
2 |     let x = 5;
  |         -
  |         |
  |         first assignment to `x`
  |         help: consider making this binding mutable: `mut x`
3 |     x = 6;
  |     ^^^^^ cannot assign twice to immutable variable

It points at the bad line, names the rule, and offers a fix: let mut x = 5;. Read these messages. They are the fastest way to learn the language.

Key insight: variables are immutable by default. To rebind, write mut.

Rust's Philosophy

Memory Safety Guarantees

Rust prevents common bugs at compile time:

Bug TypeHow Rust Prevents
Null pointer dereferenceNo null pointers (uses Option<T>)
Use after freeOwnership system
Double freeOwnership system
Buffer overflowBounds checking
Data racesOwnership + borrowing rules

The Ownership System

The core idea, expanded in Chapter 3:

  1. Each value has an owner
  2. Only one owner at a time
  3. When the owner goes out of scope, the value is dropped

That gives you memory safety without garbage collection.

Development Workflow

# 1. Create project
cargo new myapp && cd myapp

# 2. Edit code
# (use your favorite editor)

# 3. Quick check (fastest)
cargo check

# 4. Test compile
cargo build

# 5. Run
cargo run

# 6. Add dependencies (edit Cargo.toml)
# [dependencies]
# rand = "0.8"

# 7. Build with new deps
cargo build

# 8. Before commit
cargo fmt
cargo clippy
cargo test

Setting Up Your Editor

Install extensions:

  • rust-analyzer: Language server (autocomplete, go to definition)
  • CodeLLDB: Debugger
  • Even Better TOML: For Cargo.toml

Other Editors

  • Vim/Neovim: rust-analyzer with coc.nvim or native LSP
  • Emacs: rust-mode + lsp-mode
  • IntelliJ: Rust plugin
  • Sublime Text: Rust Enhanced + LSP

Common First-Day Issues

Issue: "Command not found: cargo"

Solution: Restart your terminal or run:

source $HOME/.cargo/env

Issue: Slow Compilation

Solution:

# Use cargo check for quick feedback
cargo check

# Use --release only when needed
cargo build --release

Issue: Cryptic Error Messages

Solution: Read carefully. Rust errors are detailed. Look for:

  1. The error code (e.g., E0384)
  2. The suggestion (usually after "help:")
  3. The problematic line

Practice Exercises

Exercise 1: Hello Name

Create a program that:

  1. Asks for your name
  2. Asks for your age
  3. Prints "Hello, [name]! You are [age] years old."

Exercise 2: Calculator

Create a program that:

  1. Takes two numbers as command line arguments
  2. Prints their sum

Example:

cargo run -- 5 3
# Output: 5 + 3 = 8

Exercise 3: Temperature Converter

Create a program that converts Celsius to Fahrenheit.

Formula: F = C × 9/5 + 32

Key Takeaways

  • Rust prioritises safety and performance
  • Cargo is your one tool for building Rust projects
  • The compiler is your friend. Read error messages carefully
  • Variables are immutable by default
  • Rust has no garbage collector but still guarantees memory safety

Next Steps

Continue to 02-basics.md to learn Rust's type system, variables, and basic operations.

Quick Reference Card

// Create a project
cargo new myproject

// Run a program
cargo run

// Variables (immutable)
let x = 5;

// Variables (mutable)
let mut y = 10;
y = 20;

// Print to console
println!("Value: {}", x);

// Function definition
fn main() {
    // code here
}