Basics

Updated: November 24, 2025

Learn the basic components that make up the Rust language.

Table of Contents

Borrowing

let s = String::from("hello");
let r1 = &s;         // immutable borrow
let r2 = &s;         // another immutable borrow
let r3 = &mut s;     // mutable borrow (would fail if r1/r2 exist)

Concurrency

use std::thread;
let handle = thread::spawn(|| {
    println!("Hello from a thread!");
});
handle.join().unwrap();

Enums

enum IpAddr {
    V4(u8, u8, u8, u8),
    V6(String),
}
let home = IpAddr::V4(127, 0, 0, 1);
match home {
    IpAddr::V4(a, b, c, d) => println!("{}.{}.{}.{}", a, b, c, d),
    IpAddr::V6(addr) => println!("{}", addr),
}

Errors

use std::fs::File;
fn read_file() -> Result<String, std::io::Error> {
    let f = File::open("hello.txt")?;
    Ok(String::from("file contents"))
}

Functions

fn add(x: i32, y: i32) -> i32 {
    x + y
}
let add_closure = |x: i32, y: i32| -> i32 { x + y };
let result = add_closure(1, 2);

Generics

fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
    let mut largest = list[0];
    for &item in list.iter() {
        if item > largest {
            largest = item;
        }
    }
    largest
}

Macros

macro_rules! vec {
    ( $( $x:expr ),* ) => {
        {
            let mut temp_vec = Vec::new();
            $(
                temp_vec.push($x);
            )*
            temp_vec
        }
    };
}
let v = vec![1, 2, 3];

Ownership

let s1 = String::from("hello");
let s2 = s1;         // s1 moved to s2, s1 invalid
let s3 = s2.clone(); // explicit copy
fn take_ownership(s: String) { /* s owned here */ }
fn borrow(s: &String) { /* s borrowed here */ }

Structs

struct Rectangle {
    width: u32,
    height: u32,
}
impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
    fn square(size: u32) -> Rectangle {
        Rectangle { width: size, height: size }
    }
}

Syntax

let x = 5;          // statement
let y = x + 1;      // expression
fn add(a: i32, b: i32) -> i32 { a + b }  // function

Testing

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
    #[test]
    #[should_panic]
    fn test_panic() {
        panic!("This test should panic");
    }
}

Types

let s: String = String::from("hello");
let arr: [i32; 3] = [1, 2, 3];
struct Point { x: f64, y: f64 }
enum Message { Quit, Move { x: i32, y: i32 } }

Variables

let x = 5;          // immutable
let mut y = 5;      // mutable
y = 6;
let y = y + 1;      // shadowing
const MAX_POINTS: u32 = 100_000;
static mut COUNTER: u32 = 0;