Rust Cheatsheet

Basics

Use this Rust reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Rust quick reference for software engineering interviews

Use this Rust cheatsheet when you are learning programming, practicing DSA, or doing company interview preparation in a memory-safe systems language. Try small examples in the Rust online compiler, then use the sections below while translating Meta interview questions, FAANG interview prep drills, or your own project code into Rust.

Hello World and Entry Point

fn main() {
    println!("Hello, world!");
}

Compile and run: rustc main.rs && ./main With Cargo: cargo new my_project && cargo run

Variables and Mutability

By default variables are immutable. Use mut to allow reassignment.

let x = 5;           // immutable
let mut y = 10;      // mutable
y = 20;              // ok
// x = 6;            // compile error

let z: i32 = -42;   // explicit type annotation

Shadowing — redeclare with let to transform a value:

let x = 5;
let x = x + 1;          // shadows previous x
let x = x.to_string();  // type can change when shadowing

Constants

const MAX_POINTS: u32 = 100_000;   // must have type annotation, SCREAMING_SNAKE_CASE
const PI: f64 = 3.141_592_653_589_793;
  • Evaluated at compile time.
  • Valid for entire program lifetime, in any scope.
  • Cannot use mut.

Primitive Types Quick Reference

TypeExampleNotes
i8..i128, isize-42i32Signed integers
u8..u128, usize255u8Unsigned integers
f32, f643.14f64Floating point (default f64)
booltrue, false
char'a', '🦀'Unicode scalar, 4 bytes
()()Unit type (empty tuple)

Numeric literals support _ separators: 1_000_000, 0xff, 0o77, 0b1010_1010.

Printing and Formatting

println!("value: {}", x);          // Display
println!("debug: {:?}", x);        // Debug
println!("pretty: {:#?}", x);      // Pretty debug
println!("binary: {:b}", 42);      // 101010
println!("hex:    {:x}", 255);     // ff
println!("HEX:    {:X}", 255);     // FF
println!("octal:  {:o}", 8);       // 10
println!("sci:    {:e}", 1000.0);  // 1e3
println!("width:  {:>10}", "hi");  // right-align in 10 chars
println!("pad:    {:0>5}", 42);    // 00042
println!("named:  {val}", val = 7); // named arg

// eprintln! prints to stderr
eprintln!("error: {}", msg);

// format! returns a String
let s = format!("{} + {} = {}", 1, 2, 3);

// print! / eprint! — no newline
print!("no newline");

Display vs Debug: implement Display for user-facing output, Debug (derivable) for developers.

Type Casting

let x: i32 = 42;
let y = x as f64;        // numeric cast
let b = 65u8 as char;    // 'A'
let n = true as i32;     // 1

// Lossy: truncates
let big: i32 = 300;
let small = big as u8;   // 44  (300 % 256)

Use From/Into traits for safe conversions; as is low-level and lossy.

Comments

// Single-line comment

/* Multi-line
   comment */

/// Doc comment for the NEXT item (supports Markdown)
/// # Example
/// ```
/// let x = 5;
/// ```
fn documented() {}

//! Doc comment for the ENCLOSING item (module/crate)

Operators

CategoryOperators
Arithmetic+ - * / %
Comparison== != < > <= >=
Logical&& || !
Bitwise& | ^ ! << >>
Compound assign+= -= *= /= %= &= |= ^= <<= >>=
Range.. (exclusive) ..= (inclusive)
Reference& &mut * (deref)

Rust has no ++/-- operators. Use += 1.

Cargo Essentials

cargo new my_project       # new binary project
cargo new --lib my_lib     # new library project
cargo build                # compile (debug)
cargo build --release      # compile (optimized)
cargo run                  # build + run
cargo run -- arg1 arg2     # pass args to binary
cargo test                 # run tests
cargo check                # type-check without building
cargo fmt                  # format code (rustfmt)
cargo clippy               # lint
cargo doc --open           # build and open docs
cargo add serde            # add dependency (cargo-add)
cargo update               # update Cargo.lock

Cargo.toml — manifest file:

[package]
name = "my_project"
version = "0.1.0"
edition = "2021"

[dependencies]
serde = { version = "1", features = ["derive"] }
rand = "0.8"

[dev-dependencies]
pretty_assertions = "1"

Attributes

#[derive(Debug, Clone, PartialEq)]   // derive common traits
#[allow(dead_code)]                   // suppress warning
#[warn(unused_variables)]
#[cfg(test)]                          // compile only in test build
#[cfg(feature = "serde")]            // feature flag
#[inline]                             // hint to inline function
#[must_use]                           // warn if return value unused
#[deprecated(since = "1.2", note = "use bar instead")]

// Inner attributes (apply to the enclosing item)
#![allow(unused)]   // at top of file: apply to whole crate

Scopes and Blocks as Expressions

// Blocks return the last expression (no semicolon)
let y = {
    let x = 3;
    x * x + 1  // no semicolon = returned
};  // y == 10

// Semicolons make statements return ()
let z = {
    let x = 3;
    x * x + 1;  // semicolon = () returned
};  // z == ()

Macros vs Functions

Macros end with !: println!, vec!, format!, assert!, assert_eq!, panic!, todo!, unimplemented!, dbg!.

dbg!(x + 1);          // prints: [src/main.rs:3] x + 1 = 6, returns value
assert!(x > 0, "x must be positive, got {}", x);
assert_eq!(a, b, "expected equal");
assert_ne!(a, b);
todo!("implement this");    // panics with message
unimplemented!();           // panics
unreachable!();             // panics if reached