This blog post is all about Optionals, a language concept baked into Apple’s Swift programming language. We’ll start off with a practical use case, in which we explain how optionals are used. We will then extend the example to make the code shorter, and hopefully, more readable too. We will finish with a study on optionals and where they come from, for those of you wanting more then just some examples.
Without further ado, let’s start.
What is an Optional?
As found on wikipedia, an Optional (or
Option type) represents an encapsulation of an optional value. An optional value either has a value, or it doesn’t. It essentially works as a type-safe alternative for nil.
From Objective C to Swift
We came up with this blogpost, because we tried to understand the deeper concepts behind optionals. We were porting our example application, which we use in many occasions, especially in courses. The first thing we did was porting our very simple model into Swift. The first thing we needed to tackle was how to use optionals in that model. Where is it appropriate to use them, and when is it better to avoid them.
Let’s see what our model looks like in Objective C
If we want to port this model one-on-one to Swift, we have to consider what the Objective C code’s intent is. All properties in this model, except for the fullName, are mutable. This means we can change them at will, and we can set these properties to nil.
So expressed in Swift, we came to this (this example is a mere port, without thinking about improving the code, we have more in store later)
Let’s take this step by step:
- Since all properties were mutable in Objective C, we use “var” for our properties, making them mutable in Swift.
- In Objective-C, all properties were essentially nullable, so we use optionals in Swift.1
We skipped the read-only derived full name property, because this is where we started thinking about how to implement this. Lets look at our first attempt.
Read-only properties and nil values
In the next code snippet we show the usage of our person
OK, there, same result as in Objective C. However, in Swift, we can probably do better than this. Let’s say we want to use a default firstName and lastName when they are nil. You could argue that we could assign default values to the properties right away, but that wouldn’t solve the problem when we set the values to nil again afterwards anyway. So let’s do it the Swift way.
Taking optionals into account
Now the result of printing the full name will be
The result is as we want it to be, but the solution is rather verbose. We could try to fit this in ternary operators:
Shorter (we could even go further and put everything on a single line), but we might argue that readability suffers. To improve this further, we looked at how optionals are implemented in the Swift library.
Optionals behind the scenes
Optional actually is an
enum defined like so
Indeed, if we play with optionals in a playground, an Optional is printed like either
So if optionals are just mere enums, we can use the full power of Swift by using extensions2 and even custom operators. We’re close now.
Extending Optional with an extension
Addendum: The next section was written before swift included the The nil coalescing operator. Read on, the excercise is still interesting.
Put to use in our fullName getter:
This code shows it’s intent, and reads like prose. We could stop here, but let’s see how deep the rabbit hole goes.
Using an operator to get a default value
Let’s try a custom operator to return a default value. 3
And the new version of the getter becomes:
The power of Swift is definitely at work here, although we think it might be a bridge too far. We’ll probably stick with just using the
- This might not be what we actually want, but remember, this is a mere port to Swift. We should ask ourselves if these properties are actually optional or not. The essence of an optional is that you force the user of an optional property to always check if it has a value or not, causing bloated code at times. This doesn’t mean we think optionals are bad! ↩
- Extensions in Swift are like categories in Objective-C. ↩
- Read more on operators here and here ↩