Swift Cheatsheet
Types & Protocols
Use this Swift reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Structs vs classes
struct Point { // value type, copied on assignment var x = 0 var y = 0 // memberwise init is free: Point(x: 1, y: 2) } final class Counter { // reference type, shared on assignment var value = 0 init(value: Int = 0) { self.value = value } func inc() { value += 1 } deinit { print("gone") } }
| struct / enum | class | |
|---|---|---|
| Semantics | Value, copied | Reference, shared |
| Inheritance | No (protocols only) | Yes |
deinit | No | Yes |
| Memberwise init | Generated | Write your own |
Identity (===) | No | Yes |
| Default choice | Yes | Only for identity, inheritance, or shared mutable state |
Computed properties, observers, lazy
struct Circle { var radius: Double var area: Double { // computed, read-only .pi * radius * radius } var diameter: Double { // computed get/set get { radius * 2 } set { radius = newValue / 2 } } } final class Slider { var value = 0 { willSet { print("will become \(newValue)") } didSet { print("was \(oldValue), now \(value)") } } static let shared = Slider() // type-level property } final class Report { let data: [Int] init(data: [Int]) { self.data = data } lazy var sortedData: [Int] = data.sorted() // computed once, on first access }
Access control
| Level | Visible from |
|---|---|
open | Anywhere, and subclassable/overridable outside the module (classes) |
public | Anywhere, but not subclassable outside the module |
package | Any module in the same package (Swift 5.9+) |
internal | Same module (the default) |
fileprivate | Same source file |
private | Enclosing declaration, plus its extensions in the same file |
public struct Account { public private(set) var balance = 0 // read anywhere, write internally private var pin = "0000" public mutating func deposit(_ n: Int) { balance += n } }
Enums
enum Direction: String, CaseIterable { // raw values + iteration case north, south, east, west } Direction.north.rawValue // "north" Direction(rawValue: "east") // Optional(.east) Direction.allCases.count // 4 enum LoadState { // associated values case idle case loading(progress: Double) case failed(message: String) } let state = LoadState.loading(progress: 0.4) switch state { case .idle: print("idle") case .loading(let p): print("\(Int(p * 100))%") case .failed(let msg): print(msg) } indirect enum Tree { // recursive payloads need indirect case leaf(Int) case node(Tree, Tree) }
Protocols and default implementations
protocol Named { var name: String { get } func describe() -> String } extension Named { func describe() -> String { "I am \(name)" } // default implementation } struct User: Named { let name: String } User(name: "Ada").describe() // "I am Ada" struct Cell: Equatable, Hashable, Codable { // conformances synthesized var x: Int var y: Int }
Equatable, Hashable, and Codable are synthesized automatically when every stored property conforms. Add Comparable by implementing static func < .
some vs any (opaque vs existential)
protocol Shape { var area: Double { get } } struct Square: Shape { var side: Double var area: Double { side * side } } func makeShape() -> some Shape { // opaque: one hidden concrete type Square(side: 2) } let shapes: [any Shape] = [Square(side: 2), Square(side: 3)] // boxed existentials let total = shapes.reduce(0) { $0 + $1.area }
some keeps the concrete type known to the compiler: static dispatch, no boxing, required for SwiftUI body. any erases the type into a box: heterogeneous storage and flexible APIs, with a small runtime cost. Prefer generics or some in hot paths, write any explicitly for existentials.
Macros and @Observable
import Observation @Observable final class CartModel { // Swift 5.9+ macro var items: [String] = [] var total = 0 }
@Observable replaces the older ObservableObject + @Published pattern for SwiftUI state. Attached macros (@Observable, #Predicate, custom ones) expand at compile time and are inspectable via Xcode's "Expand Macro".