Skip to the content.

Rust Cheatsheet

Rust Cheatsheet

A quick-reference guide for essential and advanced Rust concepts, covering mutability, ownership, pattern matching, error handling, traits, smart pointers, and Cargo commands.

Variables & Mutability

fn main() {
    let x = 5;                  // Immutable variable (default)
    // x = 6;                   // Error: Cannot assign twice to immutable variable

    let mut y = 5;              // Mutable variable
    y = 6;                      // Success

    const MAX_POINTS: u32 = 100_000; // Constant (must have explicit type, resolved at compile-time)
    
    // Shadowing (re-declaring variable with same name, can change type)
    let spaces = "   ";
    let spaces = spaces.len();  // Shadowed 'spaces' is now an integer
}

Ownership & Borrowing

fn main() {
    // 1. Move Semantics (Types on heap move ownership by default)
    let s1 = String::from("hello");
    let s2 = s1;                // s1 is MOVED to s2. s1 is no longer valid.
    // console.log!("{}", s1);  // Error: Value borrowed here after move

    // 2. References & Borrowing
    let len = calculate_length(&s2); // Pass read-only reference (&s2)

    // 3. Mutable References
    let mut s3 = String::from("hello");
    change_string(&mut s3);     // Pass mutable reference (&mut s3)
    
    // Borrowing Rules:
    // - You can have any number of immutable references (&T) OR
    // - Exactly ONE mutable reference (&mut T) at any given time
    // - References must always be valid (no dangling references)
}

fn calculate_length(s: &String) -> usize {
    s.len()                     // Returns size, does not take ownership
}

fn change_string(s: &mut String) {
    s.push_str(", world");      // Modifies original String safely
}

Structs & Enums

// Standard Struct
struct User {
    username: String,
    email: String,
    active: bool,
}

// Tuple Struct (Named fields are omitted)
struct Color(i32, i32, i32);

// Implementation block (defines methods)
impl User {
    fn greet(&self) {           // Method (takes &self reference)
        println!("Hello, {}!", self.username);
    }

    fn create_new(username: String, email: String) -> Self { // Associated Function (static helper)
        Self { username, email, active: true }
    }
}

// Enums with data
enum Message {
    Quit,
    Move { x: i32, y: i32 },    // Anonymous struct data
    Write(String),              // Tuple data
    ChangeColor(i32, i32, i32),
}

Pattern Matching

fn process_message(msg: Message) {
    match msg {
        Message::Quit => {
            println!("Quitting");
        }
        Message::Move { x, y } => {
            println!("Moving to x: {}, y: {}", x, y);
        }
        Message::Write(text) => {
            println!("Text: {}", text);
        }
        _ => println!("Other action"), // Default match fallback
    }
}

// if let (Destructure a single pattern cleanly)
fn check_optional(opt: Option<i32>) {
    if let Some(number) = opt {
        println!("Number is: {}", number);
    }
}

Error Handling

// 1. Unrecoverable Errors (Crash the thread immediately)
// panic!("Fatal crash occurred!");

// 2. Recoverable Errors (Option & Result)
// Option<T>: Some(T) or None (Represents presence/absence of value)
let item: Option<i32> = Some(10);
let val = item.unwrap_or(0);    // Safe unwrap with fallback default

// Result<T, E>: Ok(T) or Err(E) (Represents success or failure of operations)
fn read_username_from_file() -> Result<String, std::io::Error> {
    let mut file = std::fs::File::open("username.txt")?; // '?' operator propagates error upward instantly
    let mut username = String::new();
    std::io::Read::read_to_string(&mut file, &mut username)?;
    Ok(username)
}

Collections

// 1. Vectors (Dynamically sized arrays)
let mut v: Vec<i32> = Vec::new();
v.push(1);
v.push(2);
let third: &i32 = &v[1];        // Direct index borrow (panics if out of bounds)
let safe_third: Option<&i32> = v.get(1); // Safe retrieval (returns Some or None)

// 2. Strings vs String slices
let s1: &str = "Hello";         // String slice (fixed size, immutable reference)
let mut s2: String = s1.to_string(); // String (heap-allocated, dynamic, mutable)
s2.push_str(" World");

// 3. HashMaps
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
let team_score = scores.get("Blue"); // Returns Option<&i32>

Traits & Generics

// Generics in Structs
struct Point<T> {
    x: T,
    y: T,
}

// Traits (Interface behavior agreements)
pub trait Summary {
    fn summarize(&self) -> String;
    
    // Default implementation
    fn default_summary(&self) -> String {
        String::from("(Read more...)")
    }
}

// Implementing Traits
impl Summary for User {
    fn summarize(&self) -> String {
        format!("User: {}", self.username)
    }
}

// Trait Bounds (Restrict generics to specific trait behaviors)
pub fn notify<T: Summary>(item: &T) {
    println!("Notification: {}", item.summarize());
}

Smart Pointers

// Box<T> (Heap allocation: puts data on heap, keeps pointer on stack)
let b = Box::new(5);

// Rc<T> (Reference Counted: enables multiple read-only ownerships on single-threaded)
use std::rc::Rc;
let rc_data = Rc::new(String::from("shared"));
let ref1 = Rc::clone(&rc_data); // Increments reference count, does not copy string data

// Arc<T> (Atomically Reference Counted: safe thread-safe Rc alternative)
use std::sync::Arc;
let arc_data = Arc::new(String::from("thread-shared"));

Cargo Commands

cargo new <project_name>       # Create a new binary Cargo package
cargo build                   # Compile the current package in Debug mode
cargo build --release         # Compile package with optimizations in Release mode
cargo run                     # Compile and run the binary target
cargo test                    # Compile and run all unit and integration tests
cargo check                   # Fast check: analyze code for compile errors without writing binary
cargo clippy                  # Run linter tool to analyze styles and idiomatic warnings
cargo fmt                     # Format all files in active crate according to Rustfmt
cargo update                  # Check and update all local dependencies in Cargo.lock