One of Swift's core features is safety and optionals tie neatly into that mindset. Developers new to Swift tend to struggle with optionals. Optionals are often seen as a hindrance instead of a powerful concept of the Swift language.
A common question developers have when they learn about optionals is "Why?" In this episode of Swift Fundamentals, we take a close look at optionals. Let's start with the obvious question "What is an optional?"
What Is an Optional
The underlying concept of an optional is easy to grasp. An optional acts as a container for a value of a particular type. The container holds a value or it doesn't.
An optional acts as a container for a value of a particular type. The container holds a value or it doesn't.
In this example, we declare an optional of type String?
or optional String. The question mark indicates that we're dealing with an optional.
var message: String?
If you add this line of code to a playground and inspect the output in the results panel on the right, it should read nil
. Forget what you know about the meaning of nil
in other languages. In Swift, nil
means no value or the absence of a value. The meaning of nil
in Swift and Objective-C is very different. That's important to understand and remember.
Add the following line to your playground and take a look at the output on the right. Don't worry about the warning that pops up. Does the output in the results panel surprise you? The output shows us that we're dealing with an optional.
var message: String?
message = "I'll be home at six."
print(message)
Unwrapping Optionals
Assigning a value to an optional is identical to assigning a value to a regular variable or constant. Reading the value stored in an optional is a different story.
Because the value of an optional is wrapped in a container, you cannot access the value of an optional like you access the value of a regular variable or constant. Let's illustrate this with an example. We define a constant, body
, of type String
.
let body: String = message
The assignment of message
to body
generates an error. Click the red circle on the left to see what the error is about and what Xcode suggests we do to fix it.
Let's give Xcode's suggestion a try by appending an exclamation mark to the name of the optional. That seems to work. There's a catch, though. An exclamation mark in Swift always means you're performing an operation that can backfire. In other words, you're taking a risk.
What happens if the optional doesn't contain a value? Let's update the example to see what happens if message
doesn't contain a value.
var message: String?
let body: String = message!
When the optional message
doesn't contain a value, a runtime error is thrown. This time Xcode doesn't offer us any help. It's up to us to fix the problem.
The output in the console at the bottom gives us a hint. It's pretty obvious what the problem is.
Fatal error: Unexpectedly found nil while unwrapping an Optional value
Let's take a moment to discuss what happened and what went wrong. Let me start by explaining the meaning of the exclamation mark. By appending an exclamation mark to the name of an optional, the optional is forced unwrapped. This means that we unwrap or read the value of the optional's container no matter what it contains. If the optional has a value, we can read the value. If the optional's container is empty, a runtime error is thrown.
Optionals should never be forced unwrapped unless you are absolutely certain it contains a value.
If you force unwrap an optional that doesn't contain a value, your process or application terminates immediately. That sudden termination is the result of a runtime error. An optional should never be forced unwrapped unless you're absolutely certain it contains a value.
Inspecting an Optional
We can play it safe by asking an optional if it contains a value. We do this by asking the optional if it is equal to nil
. If it isn't, then it's safe to access its value.
var message: String? = "Hello World"
if message != nil {
print(message!)
} else {
print("No Value to Print")
}
While this strategy is safer, it isn't convenient. The Swift language defines several patterns that make working with optionals easier and more elegant. In the next episode, I show you several techniques to work with optionals in Swift.
What's Next?
Remember from this episode that optionals are an important concept of the Swift language. Developers new to Swift often struggle with optionals. That isn't uncommon. Give yourself some time to wrap your head around the underlying concept.
It's important to understand and remember what optionals stand for. Learn to embrace optionals and use them to your advantage. It's only then that you can start to appreciate the Swift language.