All cheatsheets

Cheatsheets

Rust

Ownership, borrowing & lifetimes, enums & pattern matching, Result/Option, and traits.

Test yourself

71 entries

Variables & bindings7

let x = 5;

Immutable binding by default — you can't reassign x.

let mut x = 5;

Mutable binding — x can be reassigned.

let x = x + 1; // shadowing

Shadowing — rebind the same name, even to a new type.

const MAX: u32 = 100_000;

Compile-time constant — type required, always immutable.

static GREETING: &str = "hi";

Static — a single fixed memory location, 'static lifetime.

let (a, b) = (1, 2);

Destructuring a tuple in a binding.

let _ = compute();

`_` discards a value (suppresses the unused warning).

Ownership & move semantics6

let b = a; // a moved into b

Each value has one owner; assigning a non-Copy value moves it.

i32, bool, char, f64: Copy

Small stack-only types implement Copy — assignment duplicates instead of moving.

fn takes(s: String) { ... }

Passing a value by value moves it into the function (callee owns it).

let c = a.clone();

Deep copy — explicit, potentially expensive, gives you a second owner.

drop(value);

Drop a value early; runs its Drop impl and frees resources now.

fn make() -> String { ... }

Returning a value moves ownership out to the caller.

References, borrowing & lifetimes10

&T (shared / immutable borrow)

Borrow a value to read it without taking ownership.

&mut T (exclusive borrow)

A single mutable borrow — exclusive access to mutate in place.

*r

Dereference a reference to read or write the pointed-to value.

fn borrows(s: &str)

Prefer &str over &String in parameters — accepts both, via deref coercion.

Box<T>

Owned heap allocation; single owner, for recursive types or large values.

Rc<T> / Arc<T>

Shared ownership via reference counting (Arc is thread-safe / atomic).

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str

Generic lifetime — ties the output reference's validity to the inputs.

struct Holder<'a> { part: &'a str }

A struct that holds a reference must name that reference's lifetime.

'static

Lives for the whole program — string literals, leaked/global data.

fn f(s: &str) -> &str

Lifetime elision — compiler infers obvious cases, no annotation needed.

Structs & enums7

struct User { name: String, age: u8 }

A named-field struct grouping related data.

enum Shape { Circle(f64), Rect { w: f64, h: f64 } }

Enums model 'one of several variants', each able to carry different data.

struct Point(i32, i32);

Tuple struct — fields accessed by position (.0, .1).

struct Marker;

Unit struct — no data; useful as a marker or for trait impls.

let u2 = User { age: 30, ..u };

Struct update syntax — fill remaining fields from another instance.

#[derive(Debug, Clone, PartialEq)]

Auto-implement common traits for a type.

impl User { ... }

Inherent impl block — define methods and associated functions.

Pattern matching7

match value { ... }

Exhaustive pattern matching — the compiler forces you to handle every case.

if let Some(x) = opt { ... }

Match one pattern concisely, ignoring the rest — great for Option/Result.

while let Some(x) = stack.pop()

Loop while a pattern keeps matching (e.g. draining a stack).

match n { 1 | 2 => ..., 3..=9 => ... }

Or-patterns (`|`) and inclusive ranges (`..=`).

Point { x, y: 0 } => ...

Destructure structs/tuples/enums directly in the pattern.

n if n % 2 == 0 => ...

Match guard — an extra boolean condition on an arm.

Some(x @ 1..=5) => ...

@ binding — capture the matched value while also testing it.

Option, Result & the ? operator7

enum Option<T> { Some(T), None }

Models 'a value or nothing' — Rust's safe replacement for null.

enum Result<T, E> { Ok(T), Err(E) }

Models success-or-failure — Rust's recoverable error type.

let n = s.parse::<i32>()?;

The ? operator — propagate the error/None, or unwrap the success value.

opt.unwrap_or(0) / .unwrap_or_else(f)

Provide a fallback for None/Err without panicking.

opt.map(f).and_then(g)

Transform / chain fallible computations on Option/Result.

result.expect("msg")

Unwrap, but panic with a custom message on failure (use in tests/setup).

result.ok() / .err()

Convert Result<T,E> to Option<T> / Option<E>, discarding the other side.

Traits & generics7

trait Summary { fn summarize(&self) -> String; }

Define shared behavior; types `impl` the trait to gain it.

fn largest<T: PartialOrd>(list: &[T]) -> &T

Generic function with a trait bound — works for any T that satisfies the bound.

fn notify(item: &impl Summary)

`impl Trait` in argument position — accept any type implementing the trait (static dispatch).

where T: Display + Clone

where-clause — readable home for long/complex trait bounds.

Box<dyn Trait>

Trait object — dynamic dispatch for heterogeneous values (Vec<Box<dyn Draw>>).

impl Default for T { ... }

Provide a default value; call with T::default().

T: From<U> / U: Into<T>

Convert between types; Into is auto-derived from From.

Collections, strings & iterators10

Vec<T> / &[T] / [T; N]

Growable vector, borrowed slice, fixed-size array.

String / &str

Owned, growable UTF-8 string vs a borrowed string slice.

HashMap<K, V>

Hash map; .entry(k).or_insert(v) for insert-or-update; keys need Eq + Hash.

v.iter() / v.iter_mut() / v.into_iter()

Iterate by &T / &mut T / by value (consuming the collection).

&v[1..3]

Slice a range out of a Vec/array/String (half-open: start..end).

.iter().map(...).filter(...).collect()

Lazy iterator pipelines — compose adapters, then consume once.

|x| x + 1 (closure)

An anonymous function that can capture its environment.

.enumerate() / .zip(other)

Pair items with their index / pair two iterators together.

.fold(0, |acc, x| acc + x)

Reduce a sequence to one value with an accumulator.

.find(|x| pred) / .position(...)

First matching element / its index (returns Option).

Error handling, Cargo & borrow-checker pitfalls10

fn main() -> Result<(), Box<dyn Error>>

Let main return Result so `?` works at the top level.

panic!("boom") vs Result

Panic for unrecoverable bugs; Result for expected, recoverable failures.

cargo new / build / run / test

Cargo — Rust's build tool, package manager, and test runner.

anyhow / thiserror

Ergonomic errors: anyhow for apps (one error type), thiserror for libs (derive custom errors).

#[test] fn it_works() { assert_eq!(2 + 2, 4); }

Unit test — run with `cargo test`.

E0382: use of moved value

You used a value after it was moved into something else.

E0502: mutable + immutable borrow

Tried to borrow as mutable while an immutable borrow is still live.

E0499: two &mut at once

Two mutable borrows of the same value are alive simultaneously.

E0515: returning reference to local

Returning &local fails — the local is dropped at function end; return an owned value.

E0277: trait bound not satisfied

A type lacks a required trait (e.g. used `==` without PartialEq); add the bound or derive the trait.