env.dev

Rust Cheat Sheet — Ownership & Types Quick Reference

Rust quick reference: ownership, borrowing, lifetimes, traits, enums, pattern matching, Result/Option, and common macros.

By env.dev Updated

A quick reference for Rust syntax and concepts. Covers ownership and borrowing, lifetimes, traits, enums and pattern matching, Result/Option, structs, iterators, and common macros. Written against the Rust 2024 edition (stable since Rust 1.85, February 2025); current stable is 1.96 (May 2026).

Ownership & Borrowing

ConceptSyntaxDescription
Ownershiplet s = String::from("hi")Variable owns the value
Movelet s2 = ss is moved to s2, s is invalid
Clonelet s2 = s.clone()Deep copy, both valid
Immutable borrowlet r = &sRead-only reference (multiple allowed)
Mutable borrowlet r = &mut sRead-write reference (exclusive)
Borrow rule&T or &mut T, not bothCannot mix shared and mutable refs
Copy typesi32, f64, bool, char, ..Stack types are copied, not moved

Lifetimes

SyntaxDescription
fn f<'a>(x: &'a str) -> &'a strExplicit lifetime annotation
struct S<'a> { r: &'a str }Lifetime in struct (holds reference)
impl<'a> S<'a> { }Lifetime in impl block
fn f(x: &str) -> &strLifetime elision (compiler infers)
'staticLives for entire program duration
fn f<'a, 'b>(x: &'a str, y: &'b str)Multiple lifetime parameters
where 'a: 'bLifetime bound ('a outlives 'b)

Traits

SyntaxDescription
trait Summary { fn summarize(&self) -> String; }Define a trait
impl Summary for Article { .. }Implement trait for type
fn f(x: &impl Summary)Trait bound (impl syntax)
fn f<T: Summary>(x: &T)Trait bound (generic syntax)
fn f<T: Clone + Debug>(x: &T)Multiple trait bounds
fn f(x: &dyn Summary)Trait object (dynamic dispatch)
#[derive(Debug, Clone, PartialEq)]Auto-derive common traits
trait A: B { }Supertrait (A requires B)

Enums & Pattern Matching

SyntaxDescription
enum Color { Red, Green, Blue }Simple enum
enum Shape { Circle(f64), Rect(f64, f64) }Enum with data
match x { 1 => "one", _ => "other" }Match expression (exhaustive)
match shape { Circle(r) => .. }Destructure enum variant
if let Some(v) = opt { .. }Match single pattern
while let Some(v) = iter.next() { .. }Loop on pattern match
matches!(x, Pattern)Boolean pattern check macro
match (a, b) { (1, 2) => .. }Match on tuples

Result & Option

PatternDescription
Ok(value) / Err(err)Result variants
Some(value) / NoneOption variants
result?Propagate error (early return Err)
opt.unwrap()Get value or panic — fine in tests, prefer expect("why") elsewhere
opt.unwrap_or(default)Get value or use default
opt.unwrap_or_else(|| compute())Get value or compute default
result.map(|v| transform(v))Transform Ok/Some value
result.and_then(|v| maybe_fail(v))Chain fallible operations
opt.is_some() / opt.is_none()Check variant without consuming

Structs

SyntaxDescription
struct Point { x: f64, y: f64 }Named-field struct
struct Color(u8, u8, u8)Tuple struct
struct Unit;Unit struct (no fields)
let p = Point { x: 1.0, y: 2.0 }Create struct instance
let p2 = Point { x: 3.0, ..p }Struct update syntax
impl Point { fn new(x: f64, y: f64) -> Self { .. } }Associated function (constructor)
impl Point { fn length(&self) -> f64 { .. } }Method on struct
pub struct Pub { pub field: i32 }Public struct with public field

Iterators

MethodDescription
.iter()Iterator of references (&T) — collection stays usable after
.into_iter()Iterator that consumes collection — use when you are done with it
.iter_mut()Iterator of mutable references (&mut T)
.map(|x| f(x))Transform each element
.filter(|x| predicate(x))Keep elements matching predicate
.collect::<Vec<_>>()Consume iterator into collection
.fold(init, |acc, x| acc + x)Reduce to single value
.enumerate()Yield (index, value) pairs
.zip(other)Pair elements from two iterators
.take(n) / .skip(n)Limit or skip elements

Common Macros

MacroDescription
println!("x = {}", x)Print with newline
format!("hello {name}")Format string without printing
vec![1, 2, 3]Create Vec from literal values
todo!()Placeholder for unfinished code (panics)
unimplemented!()Mark unimplemented branch (panics)
dbg!(expr)Debug print expression and value
assert!(cond)Panic if condition is false
assert_eq!(a, b)Panic if a != b
cfg!(target_os = "linux")Compile-time configuration check

Common gotchas

  • The 2024 edition made std::env::set_var and remove_var unsafe — mutating the environment is not thread-safe on POSIX. Details in the Rust env vars guide.
  • References to static mut are a hard error in the 2024 edition (a lint before). Reach for LazyLock, Mutex, or atomics instead.
  • Integer overflow panics in debug builds but wraps silently in release. If wrapping is intended, say so: wrapping_add, checked_add, or saturating_add.
  • Iterator adapters are lazy — .map(|x| send(x)) does nothing until consumed by collect, for, or sum. The compiler warns, but only at the top level.
  • Indexing a String by integer does not compile, and s[0..1] panics mid-code-point on non-ASCII text. Iterate with .chars() or .bytes() and slice on char_indices() boundaries.

Related: constants in Rust covers const vs static vs const fn, and environment variables in Rust explains env! vs env::var.

Was this helpful?

Frequently Asked Questions

What is ownership in Rust?

Ownership is Rust's memory management system. Each value has one owner. When the owner goes out of scope, the value is dropped. Values can be moved or borrowed (referenced) but not both at the same time.

What is the difference between Result and Option?

Option<T> represents a value that may or may not exist (Some(T) or None). Result<T, E> represents an operation that may succeed (Ok(T)) or fail (Err(E)). Use ? operator to propagate errors.

What are traits in Rust?

Traits define shared behavior (like interfaces). Types implement traits with impl TraitName for TypeName. Common traits: Clone, Debug, Display, Iterator, From/Into, Default.