RsRust · Lesson 8 of 8

Rust Cheatsheet

Ownership, pattern matching, and the types you use daily — one page.

Rust
// ── Basics ──────────────────────────────
let x = 42;                  // immutable by default
let mut y = 3.14;            // opt into mutation
let name: &str = "Ada";      // string slice
let owned: String = String::from("hi");
println!("{name} is {x}");   // interpolation

// ── Ownership rules ─────────────────────
// 1. every value has ONE owner
// 2. value dropped when owner leaves scope
// 3. either ONE &mut ref or MANY & refs — never both
let s = String::from("hi");
takes(s);            // moved — s unusable now
takes_ref(&s);       // borrowed — s still fine
takes_mut(&mut s);   // exclusive borrow

// ── Control flow ────────────────────────
if x > 10 { } else { }
let label = if x > 10 { "big" } else { "small" };  // expression
for i in 0..5 { }            // 0-4
for item in &items { }
while cond { }
loop { break; }

// ── Functions ───────────────────────────
fn add(a: i32, b: i32) -> i32 {
    a + b                    // last expression = return
}
let double = |n| n * 2;      // closure
Rust
// ── Enums, Option, Result ───────────────
enum Shape { Circle(f64), Rect { w: f64, h: f64 } }

match shape {
    Shape::Circle(r) => 3.14 * r * r,
    Shape::Rect { w, h } => w * h,
}                            // must be exhaustive

let maybe: Option<i32> = Some(5);
if let Some(n) = maybe { }
maybe.unwrap_or(0); maybe.map(|n| n * 2);

fn read() -> Result<String, io::Error> {
    let text = fs::read_to_string("f.txt")?;  // ? = return Err early
    Ok(text)
}

// ── Structs & traits ────────────────────
#[derive(Debug, Clone, PartialEq)]
struct Dog { name: String }
impl Dog {
    fn new(name: &str) -> Self { Self { name: name.into() } }
    fn bark(&self) -> String { format!("{} woofs", self.name) }
}
trait Speak { fn speak(&self) -> String; }
impl Speak for Dog { fn speak(&self) -> String { self.bark() } }

// ── Collections & iterators ─────────────
let v = vec![3, 1, 4];
let m: HashMap<&str, i32> = HashMap::new();
let doubled: Vec<i32> = v.iter().map(|n| n * 2).collect();
v.iter().filter(|n| **n > 1).sum::<i32>();

// ── Cargo ───────────────────────────────
// cargo new app | cargo run | cargo test | cargo clippy
// cargo add serde --features derive