x ai rust tutorial 2026-06-23

By Xah Lee. Date: .

ai answer

Rust Tutorial: From Zero to Hero (Beginner-Friendly)

Rust is a modern systems programming language that gives you C/C++ performance with memory safety without a garbage collector. It prevents entire classes of bugs (null pointer dereferences, data races, use-after-free) at compile time through its ownership system.


1. Installation

  1. Go to https://rustup.rs and run the installer.
  2. Verify installation:
rustc --version
cargo --version

cargo is Rustโ€™s build system and package manager (like npm + make).


2. Your First Program โ€“ Hello World

Create a new project:

cargo new hello_rust
cd hello_rust

Edit src/main.rs:

fn main() {
    println!("Hello, Rust! ๐Ÿš€");
}

Run it:

cargo run

You should see the greeting.


3. Variables & Mutability

Rust variables are immutable by default (great for safety).

fn main() {
    let x = 5;           // immutable
    // x = 6;            // ERROR!

    let mut y = 5;
    y = 6;               // OK

    const MAX_POINTS: u32 = 100_000;  // constant, must have type
}

Type inference is excellent, but you can annotate:

let guess: i32 = 42;

4. Primitive Data Types

Category Types
Integers i8, i16, i32, i64, i128, isize and unsigned u*
Floats f32, f64
Boolean bool
Character char (Unicode scalar value)
Tuple (i32, f64, char)
Array [i32; 5] (fixed size)
let tup: (i32, f64, char) = (500, 6.4, 'a');
let (x, y, z) = tup;

let arr = [1, 2, 3, 4, 5];
let first = arr[0];

5. Functions

fn main() {
    let sum = add(3, 5);
    println!("3 + 5 = {}", sum);
}

fn add(a: i32, b: i32) -> i32 {
    a + b          // no semicolon = return value
}

Expression vs Statement: Lines without ; are expressions.


6. Control Flow

if / else

let number = 7;

if number % 4 == 0 {
    println!("divisible by 4");
} else if number % 3 == 0 {
    println!("divisible by 3");
} else {
    println!("not divisible by 3 or 4");
}

Loops

// Infinite loop with break
let mut counter = 0;
loop {
    counter += 1;
    if counter == 10 {
        break;
    }
}

// while
while counter > 0 {
    counter -= 1;
}

// for (most idiomatic)
let arr = [10, 20, 30];
for element in arr {
    println!("{}", element);
}

// Range
for i in 1..=5 {          // 1 to 5 inclusive
    println!("{}", i);
}

7. Ownership โ€“ Rustโ€™s Superpower

Ownership rules:

  1. Each value has a single owner.
  2. When owner goes out of scope, value is dropped.
  3. You can have one mutable reference or multiple immutable references.
fn main() {
    let s1 = String::from("hello");  // s1 owns the string on heap
    let s2 = s1;                     // s1 moved to s2
    // println!("{}", s1);           // ERROR: use of moved value

    let s3 = s2.clone();             // deep copy
    println!("s2 = {}, s3 = {}", s2, s3);
}

Borrowing with references (&):

fn calculate_length(s: &String) -> usize {
    s.len()          // immutable borrow
}

fn change(s: &mut String) {
    s.push_str(", world!");
}

8. Structs

#[derive(Debug)]
struct User {
    username: String,
    email: String,
    active: bool,
}

fn main() {
    let user1 = User {
        email: String::from("alice@example.com"),
        username: String::from("alice"),
        active: true,
    };

    println!("{:?}", user1);           // Debug print
    println!("{:#?}", user1);          // Pretty print
}

Tuple structs and unit structs also exist.


9. Enums & Pattern Matching

#[derive(Debug)]
enum IpAddr {
    V4(String),
    V6(String),
}

fn main() {
    let home = IpAddr::V4(String::from("127.0.0.1"));
    let loopback = IpAddr::V6(String::from("::1"));

    match home {
        IpAddr::V4(addr) => println!("IPv4: {}", addr),
        IpAddr::V6(addr) => println!("IPv6: {}", addr),
    }
}

Option and Result<T, E> are enums built into the language:

let some_number: Option<i32> = Some(5);
let absent_number: Option<i32> = None;

// match or ?
let x: i32 = some_number.unwrap_or(0);

10. Modules & Crates

// src/main.rs
mod garden;           // looks for garden.rs or garden/mod.rs

use crate::garden::vegetables::Asparagus;

fn main() {
    let plant = Asparagus {};
}

Cargo.toml manages dependencies:

[dependencies]
rand = "0.8"

11. Error Handling

use std::fs::File;
use std::io::{self, Read};

fn read_username_from_file() -> Result<String, io::Error> {
    let mut f = File::open("hello.txt")?;
    let mut s = String::new();
    f.read_to_string(&mut s)?;
    Ok(s)
}

? operator propagates errors automatically.


12. Next Steps & Resources

Practice Projects:

Best Learning Resources:


Quick Tips: