(Swift) Work with Optionals
“Optional” is one of the important concepts when you work with Swift language. In this article, I will explain the concepts in a simple way.
0. What are Optional types?
“Optional” is just a type in Swift Standard Library as well as other types such as String, Int, etc.
Basically, an instance cannot be nil in the Swift world. Optional is used to indicate that an instance may be nil.
Any type can be declared as an optional. Here is how to declare an optional type variable.
var optionalString: String?
You might have noticed ‘?’ symbol right after ‘String’ type declaration. This is how you declare an optional. Notice this syntax is just a short form of declaration. You can even declare an optional variable using long form like below. However, using short form is the common way.
// Long form (not so common compared with short form)
var optionalString: Optional<String>
0.1 Concept of Wrapping and Unwrapping
Whenever you want to use an optional variable, you need to change the process based on its value since it might be nil. In other words, you want to process some specific code only when there is a value to use. Otherwise, you want to process some different code or do nothing at all.
Checking if there is a value in the variable or not is called unwrapping. The article from Hacker Noon provides a good example of describing wrapping and unwrapping. According to their article, wrapping a variable using optional is like wrapping a gift box. Like a box in real-life, there might be something inside or just empty. Before you show off your gift to your friends, of course you want to check if there is actually a gift or not. If it’s empty, you don’t even want to mention about it.
1. Forced Unwrapping
One easy way to unwrap an optional is called “forced unwrapping”. All you need to do is just put ‘!’ right after the optional variable name when you use it.
However, when you do “forced unwrapping”, you need to be curtain that there is a value. Otherwise, your app is going to crash.
Imagine you have Person class which has an optional String property called middleName. In order to use the property, you have to unwrap it like below.
var person = Person()
if person.middleName != nil {
print(person.middleName!)
}
2. Optional Binding
Usually, there are many cases you’re not curtain that if an optional has a value or not. “optional binding” comes in handy in that case. There are two common optional binding control structures.
First one is “if let”. Using “if let”, you can safely unwrap an optional and use the value without “!” symbol. It’s like saying “Hey, if an optional has a value, store it in another variable inside of the scope and use that new variable instead”.
if let midName = person.middleName {
print(midName) // you can use "value" without "!" here
} else {
print("This person doesn't have a middle name")
}
The other one is “guard let”. Similar to “if let”, “guard let” allows you to unwrap an optional safely. Unlike “if let”, however, “guard let” itself doesn’t do anything if the condition is true. The main purpose of using “guard let” is exit from a function early if the condition is false.
func getMiddleName() {
guard let midName = self.middleName else { return }
print(midName)
}
In the example above, “midName” constant is guaranteed to have a value. Otherwise, the function just ends its process before it reaches “print(midName)”.
3. Optional Chaining
What “optional chaining” does is similar to “optional binding”. One important difference between those two is that “optional chaining” allows you to call properties or methods on the optional variable. You literally create a chain of properties and methods.
let midName = person.middleName?.uppercased()
In the line above, “?” mark right after “middleName” property indicates that it’s an optional property and unwrap it in order to call “.uppercased()” on the property.
4. Nil-Coalescing Operator
One of the common operations when dealing with optionals is get the value or use the default value if it’s nil. nil-coalescing operator “??” make this possible. Take a look at the example below.
let defaultMidName = person.middleName ?? "Wait for it"
If the person instance doesn’t have a middle name, the person’s middleName is going to be “Wait for it”.
5. Implicitly Unwrapped Optionals
There is one more way to unwrap Optionals. Implicitly unwrapped optionals are optionals which are declared with “!” symbol.
Just like when you do “Forced unwrapping”, implicitly unwrapped optionals cannot be nil. So, you have to be curtain that it will have a value.
// It cannot be nil, so you need to assign a value later for sure
var jobTitle: String!
That’s everything! I made a playground for this article, you can take a look at the code on my github page.
References:
Swift optionals explained simply
https://hackernoon.com/swift-optionals-explained-simply-e109a4297298
Apple Developer Documentation
https://developer.apple.com/documentation/swift/optional
Swift Programming: The Big Nerd Ranch Guide (2nd Edition)
https://www.bignerdranch.com/books/swift-programming/