Rust Cheat Sheet
A searchable, printable Rust reference — ownership and borrowing, traits, pattern matching, Option and Result, iterators and Cargo. Free.
Basics
10let x = 5;
let mut count = 0; count += 1;
let x = "5"; let x: i32 = x.parse()?;
i32, u64, f64, bool, char, usize
let t = (1, "a"); t.0
let a = [0u8; 16];
const MAX_USERS: u32 = 100;
let n = big as u8;
let s: String; let sl: &str;
println!("{name} has {count}");
Ownership, borrowing & lifetimes
10let b = a; // a is moved
let b = a.clone();
fn read(s: &String) / read(&s)
fn edit(s: &mut String) / edit(&mut s)
// no &mut while & borrows live
fn greet(name: &str)
i32, bool, char, &T are Copy
fn first<'a>(a: &'a str, b: &str) -> &'a str
struct View<'a> { text: &'a str }
let s: &'static str = "literal";
Structs, enums & impl
10struct User { name: String, age: u32 }
let u = User { name, age: 30 };
let u2 = User { age: 31, ..u };
struct Meters(f64);
impl User { fn new(name: String) -> Self { ... } }
fn label(&self) -> String
fn rename(&mut self, n: String)
enum Shape { Circle(f64), Rect { w: f64, h: f64 } }
#[derive(Debug, Clone, PartialEq)]
let cfg = Config::default();
Pattern matching
10match n { 0 => "zero", _ => "other" }
match shape { Shape::Circle(r) => ... }
match n { 1..=5 => "low", _ => "high" }
match p { Point { x, y: 0 } => ... }
Some(n) if n > 10 => "big"
id @ 1..=9 => use(id)
if let Some(v) = opt { use(v); }
let Some(v) = opt else { return; };
while let Some(x) = stack.pop() { ... }
matches!(status, Status::Active)
Option & Result
12let opt: Option<i32> = Some(5);
let res: Result<T, E> = Ok(v);
let v = load()?;
opt.unwrap_or(0)
opt.unwrap_or_else(|| compute())
opt.unwrap_or_default()
opt.map(|v| v * 2)
opt.and_then(|v| v.checked_mul(2))
opt.ok_or(MyError::Missing)?
res.map_err(|e| AppError::Io(e))
opt.is_some(); res.is_err();
let v = opt.take();
Traits & generics
11trait Greet { fn hello(&self) -> String; }
trait Greet { fn wave(&self) { ... } }
impl Greet for User { ... }
fn welcome<T: Greet>(x: &T)
fn f<T>(x: T) where T: Greet + Clone
fn welcome(x: &impl Greet)
fn make() -> impl Iterator<Item = u32>
let objs: Vec<Box<dyn Greet>> = ...;
impl From<u32> for Meters { ... }
let m: Meters = 5u32.into();
impl fmt::Display for User { ... }
Collections
12let mut v = vec![1, 2, 3];
v.push(4); v.pop();
v.get(0) // Option<&T>
for x in &v { ... }
v.sort(); v.sort_by_key(|u| u.age);
v.retain(|x| *x > 0);
let mut m = HashMap::new(); m.insert(k, v);
*counts.entry(word).or_insert(0) += 1;
m.contains_key(&k); m.get(&k);
s.push_str("more"); format!("{a}{b}")
s.chars().rev().collect::<String>()
names.join(", ")
Iterators & closures
14v.iter().map(|x| x * 2).collect::<Vec<_>>()
.filter(|x| **x > 0)
.filter_map(|s| s.parse().ok())
.sum::<i32>(); .count(); .max()
.fold(0, |acc, x| acc + x)
.enumerate()
.zip(other.iter())
.take(5); .skip(2); .rev()
.flat_map(|l| l.split(' '))
.any(|x| x < 0); .all(|x| x > 0)
.find(|u| u.id == id); .position(...)
iter() &T; iter_mut() &mut T; into_iter() T
let add = move |x| x + base;
.collect::<HashMap<_, _>>()
Error handling
11fn run() -> Result<(), Box<dyn Error>>
fn main() -> anyhow::Result<()>
file.read().context("reading config")?;
anyhow::bail!("invalid input: {x}");
#[derive(thiserror::Error, Debug)]
#[error("user {0} not found")] NotFound(u64),
#[error(transparent)] Io(#[from] std::io::Error),
enum AppError { Db(String), Timeout }
let n = do_it()?; // Err auto-converts
opt.expect("config must be loaded")
eprintln!("error: {e:#}");
Smart pointers & interior mutability
11let b = Box::new(BigStruct::new());
enum List { Node(i32, Box<List>), Nil }
let a = Rc::new(data); let b = Rc::clone(&a);
let a = Arc::new(data);
let c = RefCell::new(0); *c.borrow_mut() += 1;
Rc<RefCell<T>>
let m = Mutex::new(0); *m.lock().unwrap() += 1;
Arc<Mutex<T>>
let l = RwLock::new(map); l.read(); l.write();
Cell::new(5).set(6);
let w = Rc::downgrade(&a); w.upgrade()
Concurrency & async
13let h = thread::spawn(|| work()); h.join()
thread::spawn(move || use(data))
thread::scope(|s| { s.spawn(|| ...); })
let (tx, rx) = mpsc::channel();
tx.send(job)?; let job = rx.recv()?;
let n = Arc::new(Mutex::new(0));
#[tokio::main] async fn main() { ... }
async fn fetch() -> Result<Data>
let data = fetch().await?;
let h = tokio::spawn(fetch()); h.await??;
let (a, b) = tokio::join!(f1(), f2());
tokio::time::sleep(Duration::from_secs(1)).await;
tokio::select! { r = f1() => ..., _ = f2() => ... }
Cargo CLI
12cargo new my-app
cargo add serde --features derive
cargo run
cargo build --release
cargo check
cargo test
cargo clippy -- -D warnings
cargo fmt
cargo doc --open
cargo update
cargo install ripgrep
cargo tree
No entry matches “:q”.
About Rust Cheat Sheet
This Rust cheat sheet maps the language by concept on one searchable page: basics, ownership, borrowing and lifetimes, structs, enums and impl blocks, pattern matching, Option and Result, traits and generics, collections, iterators and closures, error handling, smart pointers and interior mutability, concurrency and async, and the Cargo command line.
Ownership is the part of Rust people come back to look up, so it gets its own section next to lifetimes, borrowing rules, Box, Rc, Arc and RefCell — alongside the everyday syntax like match arms, the ? operator, iterator adapters and deriving traits.
Like every cheat sheet in this group it is free and client-side: filter rows live with the search box, hop between sections with the sticky table of contents, copy any snippet with one click and print the page as a desk reference.
How to use Rust Cheat Sheet
- Open the sheet and review the sections, from Basics and Ownership & borrowing to the Cargo CLI.
- Search for a keyword such as lifetime, match or Arc to filter the sheet live.
- Jump to Option & Result or Error handling when you need the idiomatic way to fail.
- Click a snippet or its copy icon to copy the Rust code to your clipboard.
- Use Print for a paper copy of the full Rust reference.