Cheatsheets
Swift
Optionals, structs vs classes, enums with associated values, protocols, and closures.
Test yourself64 entries
Bindings & type inference7
let x = 5Immutable constant — x cannot be reassigned (default choice).
var y = 5Mutable variable — y can be reassigned.
let pi: Double = 3.14Explicit type annotation — needed when inference can't decide or you want a wider type.
let (a, b) = (1, 2)Tuple destructuring in one binding.
let big = 1_000_000Underscores group digits in numeric literals (ignored).
typealias Handler = (Int) -> VoidAlias a type for readability — no new type created.
let s = "\(name) is \(age)"String interpolation with \(expr).
Optionals6
var name: String?Optional — a value that may be a String or nil. Swift's answer to null.
if let name = name { ... }Optional binding — runs the block only if non-nil, with name unwrapped inside.
guard let name = name else { return }Early-exit unwrap — bind for the REST of the scope, or bail out.
let port = config["port"] ?? 8080Nil-coalescing — provide a default when the optional is nil.
let n = str!Force-unwrap — CRASHES if nil. Use only when nil is a programmer error.
var x: Int!Implicitly-unwrapped optional — auto-unwraps on use (mainly for @IBOutlet / late init).
Structs vs classes (value vs reference)8
struct Point { var x, y: Double }Value type — copied on assignment/passing. Default building block in Swift.
class Person { var name: String }Reference type — variables share ONE instance; copying copies the reference.
mutating func moveBy(dx: Double) { x += dx }Methods that change a struct's stored properties must be marked mutating.
let copy = original // value type copiesValue semantics — assigning a struct/enum/tuple makes an independent copy.
final class Foo { }final forbids subclassing/overriding — enables devirtualization (faster).
if a === b { }=== / !== compare class instance identity (same object), not value equality.
deinit { cleanup() }Class-only destructor — runs when the last reference is released (ARC).
func bump(_ x: inout Int) { x += 1 }inout passes a value param by reference so the function can mutate the caller's variable.
Enums & pattern matching6
enum Direction { case north, south, east, west }A finite set of named cases — exhaustively checkable by the compiler.
enum Result { case success(Int); case failure(Error) }Associated values — each case can carry its own typed payload.
enum Planet: Int { case mercury = 1, venus, earth }Raw values — back each case with a literal (Int/String/etc.), with init?(rawValue:).
if case .loaded(let text) = state { ... }if case — match a single enum case and bind its payload without a full switch.
enum E: CaseIterable { ... }; E.allCasesCaseIterable synthesizes allCases — iterate every case.
indirect enum Tree { case leaf(Int); case node(Tree, Tree) }indirect allows recursive enums (boxed).
Protocols & extensions8
protocol Shape { var area: Double { get } }A contract of requirements types can conform to — Swift's interface mechanism.
extension Shape { func describe() -> String { ... } }Protocol extension — give EVERY conformer a default implementation/behaviour.
func paint(_ s: some Shape)some (opaque type) vs any (existential) — prefer some for one concrete-but-hidden type.
protocol Container { associatedtype Item }associatedtype — a protocol-level placeholder filled in by each conformer.
extension Int { var squared: Int { self * self } }Extend any existing type (even stdlib) with new methods/computed props.
protocol Drawable: AnyObject { }AnyObject constraint restricts conformance to classes (needed for weak refs).
func first<T>(_ a: [T]) -> T?Generics — write one algorithm that works for any type, type-safely.
func sum<S: Sequence>(_ s: S) -> Int where S.Element == Intwhere clause — add constraints on generic/associated types.
Closures6
let add = { (a: Int, b: Int) -> Int in a + b }Closure — a self-contained, first-class block of code you can store and pass.
items.map { $0 * 2 }Trailing closure — a final closure argument moves outside the parentheses.
{ [weak self] in self?.update() }Capture list [weak self] — break the retain cycle when a closure outlives its owner.
func run(_ work: @escaping () -> Void)@escaping marks a closure param that is stored / called after the function returns.
let inc = makeCounter()Closures capture by reference — returned closures keep their captured state alive.
nums.sorted { $0 > $1 }Pass a closure to customise behaviour (sort descending here).
Collections & functional APIs7
var a = [1, 2, 3]; a.append(4)Array — ordered, indexed, value-type (copy-on-write) sequence.
var d = ["a": 1, "b": 2]Dictionary — unordered key→value map; subscript returns an Optional.
let s: Set = [1, 2, 2, 3] // {1, 2, 3}Set — unordered collection of unique Hashable elements with fast membership.
nums.map { $0 * 2 }.filter { $0 > 4 }.reduce(0, +)map / filter / reduce — transform, select, and fold a sequence functionally.
for (i, v) in arr.enumerated() { }enumerated() yields (index, element) pairs while iterating.
let names = people.sorted { $0.age < $1.age }sorted(by:) returns a new sorted array (non-mutating).
Dictionary(grouping: words, by: \.first)Group a sequence into a [Key: [Element]] dictionary.
Error handling6
enum NetError: Error { case offline, badStatus(Int) }Errors are any type conforming to the Error protocol — usually an enum.
func parse() throws -> Intthrows — declares a function can fail; callers must use try.
do { try foo() } catch { print(error) }do/try/catch — run throwing code and handle errors, matching by pattern.
let x = try? foo()try? — turn a thrown error into nil (optional result); try! traps on error.
defer { file.close() }defer schedules cleanup that runs when the scope exits (even on throw/return).
Result<Int, NetError>Result enum — capture success/failure as a value (great for async callbacks).
Properties & control flow10
var area: Double { width * height }Computed property — runs code on every access; stores nothing.
var temp: Double { didSet { log(temp) } }Property observers willSet / didSet run on every change to a stored property.
lazy var heavy = expensiveBuild()lazy var — stored, computed once on first access (must be var).
static let shared = Manager()Type property — one value shared by the type itself (e.g. a singleton).
for i in 0..<n { }Ranges: 0..<n (half-open, excludes n) and 0...n (closed, includes n).
switch x { case 1...5: ...; default: ... }switch — exhaustive, pattern-matching, no implicit fallthrough.
let label = condition ? "on" : "off"Ternary conditional — pick one of two values inline.
let json = user?.address?.cityOptional chaining — call/access through optionals; the whole expression is optional.
people.sorted(using: KeyPathComparator(\.age))Key paths (\.prop) reference a property as a value — for sorting/mapping.
assert(x > 0, "must be positive")assert (debug-only) / precondition (always) document and enforce invariants.