Cheatsheet - Rust
Tooling & CLI Commands
# Cargo project management
cargo init # Initialize current directory
cargo new my_project --bin # Create new binary application
cargo new my_lib --lib # Create new library crate
# Build & Run
cargo check # Fast syntax & type check without codegen
cargo build # Debug build with debug symbols
cargo build --release # Fully optimized release build (LTO, inlining)
cargo run # Build and run target binary
cargo run --release # Run release build
# Quality & Diagnostics
cargo test # Run unit and integration tests
cargo test -- --nocapture # Run tests showing stdout
cargo clippy -- -D warnings # Run linter catching idiomatic issues
cargo fmt --check # Verify formatting against rustfmt
cargo tree # Display visual crate dependency tree
# Toolchain management (rustup)
rustup update # Update rustc and cargo
rustup target add aarch64-unknown-linux-musl
cargo build --target aarch64-unknown-linux-musl
Primitive Types & Variables
// Mutability & Type Inference
let x: i32 = 42; // Immutable by default
let mut y = 100; // Mutable variable
y += 1;
// Constants (compile-time, inlined)
const MAX_POINTS: u32 = 100_000;
static GLOBAL_NAME: &str = "APP";
// Scalar primitives
// Integers: i8, i16, i32, i64, i128, isize
// Unsigned: u8, u16, u32, u64, u128, usize
// Floats: f32, f64
// Booleans: bool (true, false)
// Chars: char (4-byte Unicode scalar)
// Tuples & Arrays
let tuple: (i32, f64, &str) = (500, 6.4, "rust");
let (a, b, c) = tuple; // Destructuring pattern
let array: [i32; 4] = [1, 2, 3, 4]; // Fixed size on stack
let zeros = [0; 64]; // 64 elements of 0
Strings: &str vs String
// &str: String slice (borrowed view into memory, UTF-8 validated)
let s1: &str = "hello world"; // &'static str stored in binary .rodata
// String: Growable, heap-allocated buffer (ptr, len, cap on stack)
let mut s2 = String::from("hello");
s2.push_str(" world");
// Conversions
let s3 = s1.to_string(); // &str to owned String
let s4 = &s2[0..5]; // Substring slice (bytes 0..5)
let formatted = format!("User {}: {}", 10, "online");
Vectors & Collections
// Vec<T>: Dynamic heap-allocated array
let mut v: Vec<i32> = vec![1, 2, 3];
v.push(4);
v.pop(); // Returns Option<i32>
let first = v[0]; // Direct index (panics if out-of-bounds)
let safe_first = v.get(0); // Returns Option<&i32> (checked)
// HashMap
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert("Blue", 10);
scores.entry("Yellow").or_insert(50); // Insert if absent
let score = scores.get("Blue"); // Option<&i32>
Structs & Enums
// Struct definition
struct User {
username: String,
active: bool,
sign_in_count: u64,
}
// Methods and Associated Functions
impl User {
// Associated function (constructor)
fn new(username: &str) -> Self {
Self {
username: username.to_string(),
active: true,
sign_in_count: 0,
}
}
// Method taking immutable reference
fn is_active(&self) -> bool {
self.active
}
// Method taking mutable reference
fn record_login(&mut self) {
self.sign_in_count += 1;
}
}
// Enums with algebraic data types
enum WebEvent {
PageLoad,
KeyPress(char),
Paste(String),
Click { x: i64, y: i64 },
}
Pattern Matching & Control Flow
// Exhaustive match
match event {
WebEvent::PageLoad => println!("Loaded"),
WebEvent::KeyPress(c) => println!("Key: {}", c),
WebEvent::Click { x, y } => println!("Clicked at ({}, {})", x, y),
_ => (), // Catch-all wildcard
}
// if let and let-else
let config_val: Option<i32> = Some(10);
if let Some(val) = config_val {
println!("Value: {}", val);
}
// Guard early return with let-else
let Some(num) = config_val else {
return;
};
Error Handling: Option & Result
// Option<T>: Some(T) or None
let item: Option<&str> = Some("data");
let val = item.unwrap_or("default");
// Result<T, E>: Ok(T) or Err(E)
fn divide(a: f64, b: f64) -> Result<f64, String> {
if b == 0.0 {
Err("Division by zero".to_string())
} else {
Ok(a / b)
}
}
// The ? operator for error propagation
fn run() -> Result<(), Box<dyn std::error::Error>> {
let res = divide(10.0, 2.0)?;
println!("Res: {}", res);
Ok(())
}
Iterators & Functional Pipelines
let nums = vec![1, 2, 3, 4, 5, 6];
// Lazily evaluated transformation pipeline
let doubled_evens: Vec<i32> = nums
.iter()
.filter(|&&x| x % 2 == 0)
.map(|&x| x * 2)
.collect();
// Useful iterator methods
let sum: i32 = nums.iter().sum();
let found = nums.iter().find(|&&x| x > 3); // Option<&i32>
let any_odd = nums.iter().any(|&x| x % 2 != 0);
Concurrency Primitives
use std::sync::{Arc, Mutex};
use std::thread;
// Shared mutable state across threads
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..5 {
let counter_clone = Arc::clone(&counter);
let handle = thread::spawn(move || {
let mut lock = counter_clone.lock().unwrap();
*lock += 1;
});
handles.push(handle);
}
for h in handles {
h.join().unwrap();
}
Recommended ReadingSponsored
Cheatsheets - Kubernetes
Cheatsheets - Cloud
Cheatsheets - Tools
Cheatsheets - Editors
Cheatsheets - Databases
Cheatsheets - Shell
Cheatsheets - Lookups


