In many languages, ANY variable can secretly be null — and the program crashes the moment you touch it. Swift quarantines that danger: a plain String can never be nil. When a value might be absent, its type says so with a question mark: String? — an optional. It holds either a wrapped value or nil, and the compiler forces you to deal with both cases before using it.
You meet optionals immediately with dictionaries. A lookup can always miss — the key might not be there — so the subscript returns String? instead of String:
let capitals = ["France": "Paris", "Japan": "Tokyo"]
capitals["Japan"] // Optional("Tokyo") — the key exists
capitals["Brazil"] // nil — no such key, but NO crash
Four ways to get the value out:
// 1. if let — run code only when there IS a value (safe)
if let city = capitals["Japan"] {
print("got \(city)")
}
// 2. guard let — handle the nil case and exit early (safe)
guard let city = capitals["France"] else {
return
}
// from here on, city is a plain String
// 3. ?? — take the value, or a fallback on nil (safe)
let city = capitals["Brazil"] ?? "unknown"
// 4. ! — force-unwrap: take the value, CRASH on nil (dangerous)
let city = capitals["Japan"]! // fine: the key exists
if let unwraps for one block; guard let unwraps for the whole rest of the function — its else must exit (e.g. return), which is why the code after it can use the value directly.
The trap:
Force-unwrapping a nil kills your program at runtime. This compiles without a single complaint:
let capitals = ["France": "Paris", "Japan": "Tokyo"]
let capital = capitals["Brazil"]! // no "Brazil" key -> nil...
...and then dies the moment it runs:
Fatal error: Unexpectedly found nil while unwrapping an Optional value
Read that message carefully — you WILL see it again. The rule: reach for if let, guard let or ?? by default, and save ! for when you can prove the value exists.
Assignment
Follow the Coding Tutorial and practice all four: create let capitals = ["France": "Paris", "Japan": "Tokyo", "Italy": "Rome"], then
- look up
capitals["Japan"], store it inlookup, and print it viaif let, - unwrap
capitals["France"]withguard let france ... else { return }and print it after the block, - print
capitals["Brazil"]with the fallback?? "unknown", - print
capitals["Italy"]!— safe here, because the key certainly exists.
The exact expected output is:
Japan -> Tokyo
France -> Paris
Brazil -> unknown
Italy -> Rome
Hint
guard let only compiles when its else block exits the function — put return inside it. The lines print with string interpolation, e.g. print("Japan -> \(city)").
Free plan: 30 tutor messages. Premium is unlimited.