Cheatsheet: Rust

Last updated 2026-08-15

Variables and Types

Immutable and mutable bindings

let name = "Alice";
let mut count = 0;
count += 1;

Common scalar and compound types

let age: i32 = 30;
let price: f64 = 19.99;
let active: bool = true;
let coords: (i32, i32) = (10, 20);
let nums = [1, 2, 3];

Shadowing

let spaces = "  hi  ";
let spaces = spaces.trim();
let spaces = spaces.len();

Control Flow

if expression

let score = 88;
let grade = if score >= 90 {
    "A"
} else if score >= 80 {
    "B"
} else {
    "C"
};

match

let day = "sat";
match day {
    "sat" | "sun" => println!("weekend"),
    _ => println!("weekday"),
}

loop / while / for

let mut n = 0;
loop {
    n += 1;
    if n == 2 { break; }
}

while n < 4 {
    n += 1;
}

for item in [10, 20, 30] {
    println!("{item}");
}

Ownership and Borrowing

Move semantics

let a = String::from("hello");
let b = a; // ownership moves to b
// println!("{a}"); // no longer valid

Borrow with references

fn len(text: &String) -> usize {
    text.len()
}

let name = String::from("Alice");
let size = len(&name);

Mutable borrowing

fn append_world(text: &mut String) {
    text.push_str(" world");
}

let mut message = String::from("hello");
append_world(&mut message);

Rule of thumb

Use owned values when you need to store or return data.
Use &T for read-only access.
Use &mut T when one caller needs to modify a value.

Structs and Enums

Struct

struct User {
    name: String,
    age: u32,
}

let user = User {
    name: String::from("Alice"),
    age: 30,
};

impl block

impl User {
    fn greet(&self) -> String {
        format!("Hi, {}", self.name)
    }
}

Enum with match

enum Status {
    Ok,
    NotFound,
}

let code = match Status::Ok {
    Status::Ok => 200,
    Status::NotFound => 404,
};

Traits

Define and implement a trait

trait Speak {
    fn speak(&self) -> String;
}

struct Dog;

impl Speak for Dog {
    fn speak(&self) -> String {
        "woof".to_string()
    }
}

Trait bounds

fn say_twice<T: Speak>(item: &T) {
    println!("{} {}", item.speak(), item.speak());
}

Error Handling

Option

let maybe_name = Some("Alice");
if let Some(name) = maybe_name {
    println!("{name}");
}

Result and match

let port: Result<u16, _> = "8080".parse();
match port {
    Ok(value) => println!("{value}"),
    Err(err) => eprintln!("{err}"),
}

? operator

fn read_name() -> Result<String, std::io::Error> {
    let text = std::fs::read_to_string("name.txt")?;
    Ok(text.trim().to_string())
}

Collections

Vec

let mut nums = vec![1, 2, 3];
nums.push(4);
let doubled: Vec<i32> = nums.iter().map(|n| n * 2).collect();

HashMap

use std::collections::HashMap;

let mut counts = HashMap::new();
counts.insert("apple", 2);
counts.entry("apple").and_modify(|n| *n += 1).or_insert(1);

Iterate

for (key, value) in &counts {
    println!("{key}: {value}");
}