thecodex.expert · The Codex Family of Knowledge
Swift

Optionals and Types

Swift's type system makes nil a first-class, explicit concern — and choosing struct over class is a deliberate design decision that changes how data behaves.

Swift 5.10+ Value semantics Last verified:
Canonical Definition

Swift Optional<T> (written T?) is a type that wraps either a value or nil — the compiler requires you to handle the nil case before using the value. Value types (struct, enum) are copied on assignment; reference types (class) are shared via pointer. Copy-on-Write (CoW) ensures that copy-heavy operations like passing a large array are O(1) until the copy is actually mutated.

The central idea

In Objective-C, sending a message to nil silently does nothing — bugs hide for months. In Swift, nil is banned from types that don't explicitly declare they can hold it. String can never be nil. String? might be. The compiler forces you to decide what happens when it is.

Optionals: if let, guard let, and ??

Swiftoptionals.swift
var name: String? = "Priya"
name = nil   // OK — String? allows nil

// if let: safely unwrap into a new non-optional binding
if let n = name {
    print("Hello, \(n)!")   // n is String here, not String?
} else {
    print("Name is nil")
}

// Swift 5.7+: shorthand — if let name (same name, no need to rename)
if let name {
    print("Hello, \(name)!")
}

// guard let: unwrap or exit early — ideal in functions
func greet(name: String?) {
    guard let name = name else {
        print("No name provided")
        return   // must exit scope here
    }
    // name is String (non-optional) from here to end of function
    print("Hello, \(name)! Your name has \(name.count) characters.")
}

// ?? nil-coalescing: provide a default
let display = name ?? "Anonymous"   // "Anonymous" if name is nil

// Optional chaining: ?. returns Optional
let count = name?.count   // Int? — nil if name is nil
let upper = name?.uppercased().prefix(3)   // chain — nil if any step is nil

Structs vs classes: value vs reference semantics

Swiftvalue_vs_reference.swift
// Struct: value type — assignment copies the value
struct Point {
    var x: Double
    var y: Double
}

var p1 = Point(x: 1.0, y: 2.0)
var p2 = p1       // p2 is a COPY of p1
p2.x = 99.0
print(p1.x)   // 1.0 — p1 is unchanged

// Class: reference type — assignment shares the reference
class Node {
    var value: Int
    init(_ v: Int) { value = v }
}

let n1 = Node(10)
let n2 = n1       // n2 points to the SAME object as n1
n2.value = 99
print(n1.value)   // 99 — n1 sees the change (same object)

// When to use each:
// struct — data models, coordinates, colors, sizes (most Swift types)
// class  — when identity matters, when sharing mutation is intentional,
//           when subclassing is needed, when UIKit/AppKit expects classes

Enums with associated values

Swift enums can carry associated values — making them more like algebraic data types than C enums. This is Swift's equivalent of Kotlin's sealed classes or Rust's enums.

Swiftenums.swift
enum NetworkResult<T> {
    case success(T)
    case failure(Error)
    case loading
}

func handleResult(_ result: NetworkResult<String>) {
    switch result {
    case .success(let data):
        print("Got: \(data)")
    case .failure(let error):
        print("Error: \(error.localizedDescription)")
    case .loading:
        print("Loading...")
    }   // switch on enum is exhaustive — compiler warns if case is missing
}

// Result is a built-in Swift enum: Result<Success, Failure>
func fetchUser(id: Int) -> Result<String, Error> {
    if id > 0 { return .success("User\(id)") }
    return .failure(NSError(domain: "App", code: 404))
}

if case .success(let user) = fetchUser(id: 42) {
    print(user)   // "User42"
}

Copy-on-Write: why passing a 10,000-element array is O(1)

Swift's standard library value types (Array, Dictionary, String, Set) use Copy-on-Write (CoW) internally. When you copy a large array, Swift doesn't immediately copy all the elements — it shares the underlying buffer between both arrays until one of them is mutated. At the point of first mutation on the copy, the buffer is duplicated. This means passing a large array to a function is O(1) if the function only reads it. Only mutation triggers the actual copy. You can implement CoW in your own types using isKnownUniquelyReferenced.

Swiftcow.swift
// Demonstrating Copy-on-Write behaviour
var a = [1, 2, 3, 4, 5]
var b = a   // O(1) — shares buffer with a

b.append(6)   // NOW the buffer is copied — a is unchanged
print(a)   // [1, 2, 3, 4, 5]
print(b)   // [1, 2, 3, 4, 5, 6]

// Custom CoW wrapper using isKnownUniquelyReferenced
final class Buffer {
    var data: [Int]
    init(_ data: [Int]) { self.data = data }
}

struct MyCollection {
    private var buffer = Buffer([])

    mutating func append(_ value: Int) {
        if !isKnownUniquelyReferenced(&buffer) {
            buffer = Buffer(buffer.data)   // copy only when needed
        }
        buffer.data.append(value)
    }
}

Property wrappers: @State, @Published, and custom wrappers

Property wrappers (@propertyWrapper) add custom storage and behaviour to properties. SwiftUI's @State, @Binding, @Published, and @EnvironmentObject are all property wrappers. They abstract boilerplate — @State var count = 0 is equivalent to creating a State<Int> struct, accessing .wrappedValue for reads, and .projectedValue (accessed via $count) for the binding.

Commonly confused
let on a struct vs class behaves differently. let p = Point(x: 1, y: 2) — you cannot change p's properties because the entire struct value is frozen. let n = Node(10) — you cannot change which Node n points to, but you can still do n.value = 99 because Node is a class (reference type). The let freezes the reference, not the object's internals.
Optional is not a pointer to nil — it is an enum. Optional<String> is defined as enum Optional<T> { case some(T); case none }. nil is syntactic sugar for .none. name? is syntactic sugar for Optional<String>. This means optional chaining, if let, and switch are all just pattern-matching on an enum — the same mechanism as any other enum.
mutating functions are a struct concept only. Methods on a struct that modify self must be marked mutating — this signals that the caller's copy will be updated. Classes don't need (or use) mutating because class methods can always modify the shared instance. If you're seeing a compiler error about mutating a struct property in a function, the fix is to add mutating to the method.

Optional as a generic enum: the formal model

Swift's Optional<T> is defined in the standard library as a @frozen enum with two cases: case none and case some(Wrapped). @frozen means no new cases will ever be added — the compiler can use exhaustive pattern matching without a default case, and can represent Optional<Int> as a single machine word (using a sentinel value for nil when the wrapped type permits). T? is syntactic sugar for Optional<T>. Optional chaining (foo?.bar?.baz) desugars to nested map/flatMap calls on the Optional monad. The ?? operator is defined as func ??<T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T — the @autoclosure ensures the right-hand side is only evaluated if needed (lazy evaluation).

Existential types and any Protocol

Swift 5.7 introduced the any keyword for existential types — any Drawable is a type-erased box that can hold any value conforming to Drawable. Before Swift 5.7, using a protocol name directly as a type created an implicit existential (deprecated). Existentials have runtime overhead: they use a 5-word representation (value buffer + type metadata + witness table). The some keyword (opaque types) is the compile-time alternative: some Drawable is a specific unknown-to-the-caller type that conforms to Drawable — the compiler resolves the concrete type at compile time with no boxing overhead. SwiftUI uses some View for this reason.

Specification reference

Apple Inc. The Swift Programming Language. docs.swift.org/swift-book/. Chapters: Optionals, Enumerations, Structures and Classes, Value and Reference Types. Apple Inc. Swift Standard Library source. github.com/apple/swift. Swift Evolution SE-0352 (any keyword), SE-0309 (unlock existentials for all protocols).

Sources

1
Apple Inc. The Swift Programming Language. docs.swift.org/swift-book/. — Optionals, Enumerations, Structures and Classes.
2
Apple Inc. Swift Standard Library. github.com/apple/swift. — Optional enum definition.
3
Hudson, P. (2023). Hacking with Swift. hackingwithswift.com. — Practical optional and type usage.
4
Swift Evolution. github.com/apple/swift-evolution. — SE-0352 (any), SE-0244 (opaque result types).
5
Apple WWDC sessions. developer.apple.com/videos. — "Embrace Swift generics" (2022), "Design protocol interfaces in Swift" (2022).
Source confidence: High Last verified: Primary source: The Swift Programming Language — docs.swift.org/swift-book/