Resources

Vocabulary

Every key Rust term organized by topic. Use this alongside the flashcard decks.

Deck 01

The Basics

Term What it is When it's used
letCreates a new variableEvery time you store a value
mutAllows a variable to change after it is setWhen your program needs to update state
ImmutableCannot change after being setDefault Rust variable behavior
VariableA named valuelet age = 25;
Unit type ()Rust's empty value — means "nothing"When a function returns nothing meaningful
IntegerA whole numberCounts, balances, indexes
Signed integer iInteger that can be negative (i8, i32, i64)Temperatures, gains/losses
Unsigned integer uInteger that cannot be negative (u8, u32, u64)Balances, counts, addresses
u64Unsigned 64-bit integer — whole number, no negativesPayment amounts, token balances, timestamps
u8Unsigned 8-bit integer — 0 to 255Bytes, wallet address components
Floating point fA decimal number (f32, f64)Measurements — rarely used in Solana
f64A 64-bit decimal numberAvoid in Solana — use integer lamports instead
booltrue or false — nothing elseStatus flags: is_paid, is_verified
charOne character — single quotes'A', '🔥' — single symbols, not strings
&strA piece of text — borrowed string sliceLabels, names, error messages
StringOwned, growable textText you build or change at runtime
TupleA group of mixed-type values — fixed size("Alice", 25, true)
ArrayA fixed list where every item is the same type[1, 2, 3]
SliceA borrowed window into part of an array&scores[1..4] — start included, end excluded
asConverts one type to anotherWhen you need two different types to work together
println!Prints a line to the terminalDebugging or showing output
{:?}Debug print formattingPrinting arrays and tuples that {} cannot print
[u8; 32]An array of exactly 32 unsigned bytesWallet addresses on Solana
ShadowingReusing a variable name with a new let binding — the old value is replacedTransforming a value while keeping the same name
_Prefix for variables the compiler should not warn about as unused; also ignores a value in patternslet _unused = 5; or skipping a tuple element
DestructuringUnpacking a tuple or struct into individual named variables in one linelet (plan, fee) = (1_000_000u64, 50_000u64);
constA value that never changes — must have an explicit type; cannot be computed at runtimeconst MAX_FEE: u64 = 50_000; — storing fixed limits
Deck 02

Functions

Term What it is When it's used
fnThe keyword that starts a function definitionEvery function you write
FunctionA named block of code with typed inputs and optional outputAny time you want reusable logic
ParameterA typed input slot in the function signature: name: &strWhen declaring what a function accepts
ArgumentThe actual value passed when callingWhen you call a function
->Arrow separating parameters from the return typeWhen a function gives a value back
Return typeThe type of value a function sends backDeclared after -> — if you declare it, you must return it
returnSends a value back to the caller and exits the functionAt the end of a function that gives something back
format!Macro that builds a new String from a templateWhen you need text as a value, not printed
#[allow(dead_code)]Suppresses the "function never used" compiler warningDuring development before all functions are wired up
AttributeA tag above an item that changes how the compiler processes it#[allow(dead_code)], #[derive(...)]
Implicit returnThe last expression in a function body without a semicolon is automatically returnedfn add(x: i32, y: i32) -> i32 { x + y }
ScopeThe block of code where a variable is valid — from its declaration to the closing }A variable declared inside { } cannot be used outside that block
Diverging functionA function that never returns to the caller — its return type is !When a function always panics, loops forever, or exits
! (never type)The return type of a function that never returnsfn never_return() -> ! { panic!() }
unimplemented!A macro that panics with "not yet implemented" — used as a placeholderWhen writing function structure before filling in the logic
todo!A macro that panics with "not yet implemented"Placeholder for code you plan to write later
Deck 03

Ownership

Term What it is When it's used
OwnerThe variable responsible for a value — when it goes out of scope, the value is freedAlways — every value has exactly one
MoveTransferring ownership to a new variable — the original can no longer be usedWhen passing a String or Vec to a function
CopyDuplicating a value so both the original and the new variable stay validIntegers, booleans, floats — they copy automatically
CloneAn explicit full copy of a heap-allocated values1.clone() — use when you need two separate values
DropWhen a value goes out of scope and its memory is freedHappens automatically at the } that closes the scope
StackFast memory for values with a known, fixed sizei32, bool, char — automatically freed when a function ends
HeapFlexible memory for values that grow or have unknown sizeString, Vec — requires ownership tracking to know when to free
Ownership rulesRust's three rules: one owner, one owner at a time, dropped when owner goes out of scopeThe foundation of how Rust manages memory without a garbage collector
Ownership into functionPassing a String to a function moves ownership — the caller's variable is no longer validWhen a helper takes a value and the caller still needs it afterward
Return ownershipA function can give ownership back by returning the valueThe only way to use a value in main after passing it to a function that takes ownership
as_bytes()Borrows a String as a byte slice — the original string stays validWhen you need to inspect bytes without consuming the string
into_bytes()Consumes a String and converts it to a Vec<u8> — the original is gone afterwardWhen you need the raw bytes and will no longer use the string
Box<T>Allocates a value on the heap and gives you a pointer to itWhen you need to heap-allocate a type that would normally go on the stack
Mutability on transferWhen ownership moves, the new variable sets its own mutabilitylet mut s1 = s; — s1 can be mutated even if s was immutable
Deck 04

Borrowing

Term What it is When it's used
Borrow &TA read-only reference — use a value without taking ownershipWhen a function only needs to read a value
Mutable borrow &mut TA read-write reference — use and change a valueWhen a function needs to modify a value
ScopeThe block a variable lives in — between { and }Determines when a value is dropped
LifetimeHow long a reference stays valid — compiler tracks this automaticallyYou read lifetimes in Anchor ('info); rarely write them yourself
Borrowing rulesEither one mutable reference OR any number of immutable ones — never both at the same time; references must always be validHow Rust prevents data races and dangling pointers at compile time
Dangling referenceA reference to data that has already been freedRust refuses to compile this — it catches it before your code runs
&'static strA string slice that lives for the entire program lifetimelet s: &'static str = "hello"; — the value is baked into the binary
String slice [start..end]A borrowed view into part of a String — returns &str; end index is excluded&s[0..5] — the first 5 characters without taking ownership
push_str()Appends a &str to a mutable Strings.push_str("_pro"); — adding multiple characters
push()Appends a single char to a mutable Strings.push('!'); — adding one character
as_str()Converts a String to a &str — borrows without movingWhen a function expects &str but you have a String
.to_string()Converts a &str to an owned String"basic".to_string() — when you need to own a copy of a string literal
chars()Returns an iterator over the individual characters of a stringfor c in s.chars() { ... } — the safe way to loop over characters
Slice &[T]A borrowed view into part of a collection — does not take ownership&arr[1..3] — borrows elements 1 and 2 from an array
Array [T; N]A fixed-size collection where every element is the same type — length is part of the type[i32; 5] — an array of 5 integers; length must be known at compile time
.get(i)Returns Option<&T> for an index — safe access that returns None instead of panickingarr.get(10) — use when the index might be out of bounds
Deck 05

Modules

Term What it is When it's used
modDeclares a moduleEvery time you create or reference a module
pub mod helpers;Tell Rust to include helpers.rs as a moduleIn main.rs or lib.rs when code is split into files
pub fnA public function — callable from outside its moduleAny function another file needs to use
Private by defaultEverything inside a module is hidden unless pub is writtenDefault Rust behavior — you choose what is visible
::Module path separatorWhen navigating into a module: helpers::function_name
PathThe full address of a function: helpers::get_full_nameWhen calling a function from another module
Child moduleA module declared inside another moduleWhen you want to group within a module further
Inline modulepub mod name { ... } — body is right here, not a fileSmall sub-groups that do not need their own file
File-backed modulepub mod name; — body is in name.rsMost common for larger code — keeps files separate
PackageThe whole project — what cargo new createsThe container for all your crates
CrateA compilation unit — either binary or libraryThe unit Rust actually compiles
Binary crateBuilt from main.rs — produces an executable you can runRegular programs with fn main
Library crateBuilt from lib.rs — no fn mainReusable code and every Anchor program
Crate rootThe starting file for compilation (main.rs or lib.rs)Where absolute paths begin
crate::Start an absolute path at the crate rootWhen calling across modules — always correct even if code moves
super::Go up one module levelCalling a function in the parent module
useBring a path into scope as a shortcutWhen you want to stop typing the full path every call
pub useBring into scope AND re-export it to callersMaking internal paths publicly accessible — Anchor uses this
asRename an importWhen two imports share the same name
Nested pathuse x::{a, b, c} — import multiple things from one parentKeeps the import section tidy
Glob *Import everything public from a pathuse anchor_lang::prelude::* — one line for everything
Deck 06

Structs + Enums

Term What it is When it's used
StructA custom type that groups named fields togetherDefining account data, payment plans, subscribers
FieldOne named value inside a structusername: String, balance: u64
InstanceA specific struct with actual values filled inlet user = User { username: "Alice", ... }
implWhere you attach methods to a structAdding functions that belong to the struct
selfThe current instance inside an impl block — &self reads, &mut self modifiesInside any method on a struct
#[account]Anchor macro that turns a struct into a serializable on-chain accountEvery account that stores data on Solana
EnumA type that can be exactly one of several named optionsSubscription status, payment state, instruction results
VariantOne of the options inside an enum: Active, ExpiredMatching or creating an enum value
matchHandles every variant of an enum — compiler enforces completenessBranching on a Result, Option, or custom enum
Option<T>Either Some(value) or None — Rust's way of saying "might not exist"Any value that could be absent — replaces null
Result<T, E>Either Ok(value) or Err(error) — success or failureAny operation that can fail
#[error_code]Anchor macro for defining custom program errors as an enumWhen your program needs specific error messages
require!Anchor macro for validation — returns your error if a condition failsChecking conditions before processing a payment
MethodA function in an impl block that takes self, &self, or &mut self as its first parameterwallet.deposit(amount) — the function belongs to the struct
&selfGives read-only access to a struct instance inside a methodfn balance(&self) -> u64 — when the method only needs to read fields
&mut selfGives mutable access to a struct instance inside a methodfn deposit(&mut self, amount: u64) — when the method needs to modify the struct
Associated functionA function in impl with no self parameter — called with :: not .Wallet::new() — the idiomatic Rust constructor pattern
#[derive(Debug)]An attribute that gives a struct or enum the ability to be printed with {:?}Add above any struct you want to inspect during development
Field init shorthandWhen a variable name matches a field name, you can write it onceUser { email, username } instead of User { email: email, username: username }
Struct update syntax..other copies all remaining fields from an existing instancelet user2 = User { email: new_email, ..user1 };
Vec<T>A growable list where all elements are the same typelet mut v: Vec<u64> = Vec::new(); v.push(1_000_000);
Some(value)The Option variant that contains a valueSome(42) — when the result is present
NoneThe Option variant that means no value — Rust's replacement for nullNone — when there is nothing to return; must be handled explicitly
Ok(value)The Result variant for success — holds the return valueOk(new_balance) — the operation worked
Err(reason)The Result variant for failure — holds the error reasonErr("Insufficient funds") — the operation failed; caller must handle it
Deck 07

Error Handling + Traits + Generics

Term What it is When it's used
Result<T, E>Either Ok(value) or Err(error) — never bothAny function that can succeed or fail
Option<T>Either Some(value) or None — Rust's version of "might not exist"Any value that could be absent
? operatorPropagates an error up — if Err, return it; if Ok, unwrap and continueInside functions that return Result — keeps code clean
require!Anchor macro — check a condition, return a custom error if falseValidating payment amounts, account states, permissions
#[error_code]Anchor attribute — marks an enum as a set of program error typesDefining all the ways your program can fail
TraitDefines shared behavior — like an interfaceWhen different types need to do the same thing
DisplayTrait for how a type prints with {}Implementing human-readable output
DebugTrait for how a type prints with {:?}Printing structs during development
CloneTrait that makes an explicit copy of a valueWhen you need a duplicate of a struct
CopyTrait for implicit copies — integers and booleans are CopySimple types that should copy automatically
PartialEqTrait that allows == comparisons between two valuesTesting whether two values are equal
AnchorSerializeConverts a struct to bytes to store on-chainRequired on every Anchor account struct
AnchorDeserializeReads bytes from an account and rebuilds the structRequired on every Anchor account struct
DefaultProvides a zero or empty starting value for each fieldInitializing account data with safe defaults
Generic <T>A placeholder type — filled in when the code is actually usedWriting functions or structs that work with any type
Lifetime 'aA label for how long a reference stays validTelling the compiler when a reference must still be alive
'infoThe standard lifetime name in Anchor context structsEvery Context<'info, T> in an Anchor instruction
MonomorphizationRust compiles a separate version of generic code for each type used — no runtime costHappens automatically — explains why generics are fast
Recoverable errorAn expected failure the program can handle and keep runningUser overdraft, missing account, invalid input — use Result
Unrecoverable errorA programming mistake so severe the program cannot safely continueUse panic! — the only safe response is to stop immediately
Error propagationPassing an error up to the calling function with ? instead of handling it locallyWhen a function is not the right place to decide what to do with an error
Static dispatchThe compiler resolves the exact type at compile time — faster; no runtime overheadimpl Trait in function parameters
Dynamic dispatchThe type is resolved at runtime using a V-table — slightly slower but flexibleBox<dyn Trait> — needed when you do not know the type until runtime
Deck 08

Anchor + Solana

Term What it is When it's used
AnchorA framework for writing Solana programs — handles boilerplate and security checks automaticallyEvery Anchor program you write
#[program]Marks the module that contains your instruction handlersThe main module in every Anchor program
#[account]Turns a struct into an on-chain account with automatic serializationEvery struct that stores data on Solana
#[derive(Accounts)]Generates account validation code for an instruction's input structEvery instruction accounts struct
Context<T>The first parameter of every instruction — holds all accounts and program dataEvery instruction handler
ctx.accountsAccess the accounts passed into an instructionInside any instruction handler
Account<'info, T>A validated, deserialized account of type TWhen you want Anchor to check and load an account
Signer<'info>An account that must have signed the transactionValidating who is allowed to call an instruction
SystemProgram<'info>The Solana system program — handles account creationWhen creating new accounts
PDAProgram Derived Address — an account address controlled by your program, not a private keyStoring per-user state like subscriptions
seedsThe values used to derive a PDA address#[account(seeds = [b"subscription", user.key().as_ref()])]
bumpA nonce added to make the PDA address valid — stored in the accountPart of every PDA derivation
initAnchor constraint that creates a new accountWhen an instruction needs to set up a new on-chain account
mut constraintMarks an account as writable — required to change its data#[account(mut)] on any account you modify
has_oneValidates that one account's field matches another account's keyChecking that a subscription belongs to the right plan
closeAnchor constraint that closes an account and returns its rent to a walletWhen a subscription is cancelled
IDLInterface Definition Language — the JSON file Anchor generates describing your programUsed by clients (TypeScript) to interact with the program
LamportThe smallest unit of SOL — 1 SOL = 1,000,000,000 lamportsAll payment amounts in Solana programs
PubkeyA 32-byte public key — identifies a wallet or account on SolanaStoring addresses in account structs
transferMoves lamports from one account to anotherProcessing payments in a subscription program
Discriminator8 bytes Anchor adds to every account to identify its typeAutomatic — prevents account confusion attacks
SpaceThe number of bytes to allocate when creating an accountspace = 8 + 32 + 32 + 1 + 8 + 1 — must be exact