Optionals, the basics
Unit 3 · Optionals & control flow. This is the unit where Swift's "there might be no value" story gets first-class syntax. Everything here builds on the value model from Unit 1.
Most languages let any reference silently be null. Swift refuses: a value that might be
absent must say so in its type, as an optional. String always holds a string;
String? holds a string or nothing. The compiler then forces you to deal with the
"nothing" case before you can use the value — which is how a whole class of null-crashes
never happens in the first place.
An optional is just an enum
Optional is not magic syntax bolted onto the language. It's an ordinary enum in the
standard library:
enum Optional<Wrapped> { case none // written as nil case some(Wrapped) // the value is present }
String? is sugar for Optional<String>, and nil is sugar for .none. Knowing this
demystifies everything that follows: unwrapping an optional is just checking which case
you're in.
var name: String? = "Ada" // .some("Ada") name = nil // .none
Unwrapping with if let
You can't use the value inside an optional directly — you have to get it out. The everyday
tool is optional binding with if let:
let stored: String? = "Ada" if let name = stored { print("Hello, \(name)") // name is a non-optional String in here } else { print("No name") }
Inside the if let branch, name is a plain String, already unwrapped. Swift also lets
you shadow the same name, which is the idiomatic form:
if let stored { // binds `stored` as non-optional inside the block print(stored.count) }
The force-unwrap footgun
The ! operator force-unwraps: "trust me, this isn't nil." If you're wrong, the program
crashes.
let raw: String? = nil let value = raw! // 💥 runtime trap: unexpectedly found nil
Force-unwrap is not "the quick way to unwrap" — it's an assertion that nil is impossible here, and you're staking a crash on it. In production code it should be rare and always justified.
Treat ! as a claim you must defend. Every ! says "I guarantee this is non-nil." If you
can't state why out loud, use if let, guard let, or ?? instead. The most common
crash in shipping iOS apps is a force-unwrap that was true in testing and nil in the field.
This will feel familiar: Kotlin's String vs String? is the same split, and !! is
Kotlin's force-unwrap with the same "crash if null" semantics as Swift's !. Swift's if let
is Kotlin's smart-cast / ?.let { }. The mental model transfers almost one-to-one.
Your turn
Model a failable operation by returning an optional instead of crashing.
Knowledge check
Q: What are the two cases of Optional, and what does nil correspond to?
.some(Wrapped) when a value is present and .none when it's absent. nil is .none.
Q: Why prefer if let over !?
if let handles the nil case safely and gives you a non-optional binding; ! crashes if the
value is nil. Use ! only when nil is genuinely impossible and you can justify it.