# Optionals — Swift

Source: https://www.skillbyai.com/en/swift/o-optionals

> Handle missing values safely with optional binding, guard, nil coalescing and optional chaining.

## Making absence explicit

An **optional** (`String?`, short for `Optional<String>`) either contains a value or is **`nil`**. Non-optional types can never be nil, so the compiler forces you to handle the missing case before using an optional's value. Ways to unwrap: **optional binding** with `if let name { ... }` (shorthand since Swift 5.7) or `if let n = name`; **`guard let`**, which unwraps and **exits early** if nil, keeping the happy path unindented; the **nil-coalescing operator** `??` to supply a default; and **optional chaining** `user?.address?.city`, which returns nil if any link is nil. **Force unwrapping** with `!` crashes if the value is nil; use it only when nil would be a programming error that should stop the app, and even then prefer a clear `guard ... else { fatalError("reason") }`. Many APIs return optionals: dictionary lookups, `Int("42")` conversions, `first` on collections. Optionals are really an enum with `.some(value)` and `.none`, so they work with `switch` and `map`/`flatMap` too.

## A box that may be empty

An optional is a box: you must check whether something is inside before using it.

![Two small boxes side by side, one containing a value shape and one empty, with a magnifying glass above them.](assets/figures/swift/section-2-map.svg) — Figure 2.1 — Optional values with and without contents.

## Unwrapping optionals safely

guard for early exit, ?? for defaults and optional chaining.

```swift
struct User { let name: String; let address: Address? }
struct Address { let city: String }

func shippingLabel(for user: User?) -> String {
    guard let user else {
        return "Guest checkout"            // early exit when nil
    }
    let city = user.address?.city ?? "City not set"
    return "\(user.name), \(city)"
}

let ages = ["asha": 24, "ravi": 31]
if let age = ages["asha"] {               // dictionary lookups return optionals
    print("Asha is \(age)")
}

let input = "42"
let quantity = Int(input) ?? 1            // conversion may fail -> default

let scores = [91, 64, 78]
let best = scores.max()                   // Int? because the array could be empty
```

## Every ! is a possible crash

Force unwrapping is the most common cause of Swift crashes in real apps. When you write `!`, ask what happens if the value is nil, and handle that case explicitly instead.

**Quiz:** What does `guard let user else { return }` do when user is nil?

- [ ] Crashes the program
- [ ] Assigns a default user
- [x] Exits the current scope early via the else branch
- [ ] Continues with user as nil

*Answer:* Exits the current scope early via the else branch. guard requires the else branch to exit; after it, user is unwrapped for the rest of the scope.
