Optionals

6.1 What Are Optionals?

An optional (T?) either contains a value of type T or nil (no value). Swift forces you to handle the nil case explicitly.

var nickname: String? = nil
nickname = "Ace"
let number: Int? = Int("123")        // conversion may fail

6.2 Unwrapping Techniques

// 1. Optional binding (if let)
if let nickname {                     // shorthand (Swift 5.7) for `if let nickname = nickname`
    print("Hi, \(nickname)")
} else {
    print("No nickname")
}

// 2. guard let (early exit; the unwrapped value stays in scope)
func greet(_ name: String?) {
    guard let name, !name.isEmpty else {
        print("Missing name")
        return
    }
    print("Hello, \(name)")
}

// 3. Nil-coalescing
let displayName = nickname ?? "Guest"

// 4. Optional chaining
let length = nickname?.count           // Int?
let upper = user?.address?.city?.uppercased()

// 5. Force unwrap (crashes if nil: use only when nil is impossible)
let definitelyThere = Int("42")!

// 6. Multiple bindings and conditions
if let a = Int("4"), let b = Int("2"), b != 0 {
    print(a / b)
}

// 7. map / flatMap on optionals
let doubled = Int("21").map { $0 * 2 }          // Optional(42)
let parsed = "5".isEmpty ? nil : Int("5")
let chained = Optional("7").flatMap(Int.init)   // Optional(7)

// 8. switch on optionals
switch number {
case .some(let value) where value > 100: print("big \(value)")
case .some(let value): print(value)
case .none: print("nil")
}

6.3 Implicitly Unwrapped Optionals

var label: String! = "Ready"           // used mainly for IBOutlets and two-phase init
let len = label.count                   // auto-unwrapped (crashes if nil)

6.4 Optional Best Practices

Prefer if let / guard let / ?? over !. Use guard for preconditions (early exits).

Model "no value" with optionals instead of sentinel values (-1, "").

Optionals are just an enum: enum Optional<Wrapped> { case none; case some(Wrapped) }.