Optionals and nil
A Sprout habit may or may not have a reminder time. In many languages "no reminder" is a hidden null waiting to crash the app. Swift puts the maybe right in the type, and will not let you forget it.
The rule
A
?means "maybe nothing": unwrap it before you use it.
An optional is a value that is either there or nil, meaning nothing. You write it with a question mark after the type:
var reminder: String? = nil // no reminder yet
reminder = "7:30 AM" // now there is oneA plain String can never be nil. That is the promise: if the type has no ?, the value is always there.
You cannot use an optional as if it were the plain value. First unwrap it:
if let reminder {
print("Reminder at \(reminder)") // here reminder is a plain String
} else {
print("No reminder set")
}if let reminder checks for a value and, if there is one, gives you a non-optional reminder inside the braces. You can also give it a new name: if let time = reminder.
Inside a function, guard let unwraps and exits early when the value is missing:
guard let reminder else { return }
print(reminder) // usable for the rest of the functionTwo more tools:
- Optional chaining,
reminder?.count: ifreminderisnil, the whole thing isnil; otherwise it is the count, still wrapped asInt?. - Force unwrapping,
reminder!: takes the value and crashes if it isnil. Use it only when anilwould mean a bug you want to hear about.
The shortcut
When you see a ? type, ask "what should happen when it is nil?" Your answer picks the tool: do something else → if let with else; leave the function → guard let; carry the nothing along → ?..
Look at the type
reminderisString?, so it might benil.
Drills
Answer fast — trust the rule.
Which declaration allows nil?
What happens when reminder! runs and reminder is nil?
With let reminder: String? = "9 AM", what type is reminder?.count?
A function should stop early when a habit has no reminder. Which tool fits best?
Remember
- A
?means "maybe nothing": unwrap it before you use it. - Decide the nil case first:
if let,guard letor?.. !crashes on nil, so treat it as a claim that nil is a bug.
