Understanding Optionals

      No Comments on Understanding Optionals

This week we'll dive in a bit deeper. We'll take a look at the implementation of the optionals, optional chaining, nil-coalescing operator and a few more goodies.Last week we covered some basics on Optionals. This week we’ll dive in a bit deeper. We’ll take a look at the implementation of the optionals, optional chaining, nil-coalescing operator and a few more goodies. Granted, you’ll probably do just fine knowing the basics, but it’s fun to know how things work. And by the end of this article you’ll see that there’s nothing magical about optionals.

‘Optional’ enum

Optionals are nothing more than enums with two cases .none and .some. Of course, the .some case has an associated value. Optionals are so widely used in swift that there’s a lot of syntactic sugar around them. For example, if you wanted to define on optional Int, you can do it like this:

Here we can see that the ‘?’ operator is actually a shorthand version of ‘Optional<Wrapped>’. If we dive a bit deeper and go to the definition of the ‘Optional<Wrapped>’ we’ll see that it’s just an enum. It has two main cases, like so:

Of course this means that we can use the enum cases everywhere in the code. For example, if we wanted to define a function that returns an optional Int, we could write it like this:

There’s a shorter way of writing the same function, like so:

Your .none case gets replaced by nil, and the associated value gets ‘extracted’ automatically. Because of all this syntactic sugar, you probably won’t use the ‘Optional’ enum directly in your day-to-day development.

Optionals With ‘switch’ Statement

Since optionals are actually enums, it’s only natural that we can use a switch statement with optionals. You could, for example, do some custom filtering like this:

Pretty cool, right. Let’s move on to optional chaining.

Optional Chaining

Let’s say you have a class that has properties of an optional type. For example, your object graph might look something like this:

If you need to access the ‘name’ property of the engine using optional binding, things might get a bit verbose:

While this is not as bad as the earlier versions of swift, it can still be a bit hard to read. Luckily there’s a better way of doing this using optional chaining:

We’re unwrapping optional values here using the ‘?’ operator. If at any point the unwrapping operation returns nil the optional binding will fail and the ‘if let’ block won’t get executed. This is definitely a lot more readable.

Nil-coalescing operator

This is just a fancy way of saying ‘default value’ when working with optionals πŸ™‚ Let’s say you’re trying to unwrap an optional and if it’s nil, you want to use a default value. You have a few options. The most obvious, and the most verbose would be something like this:

You might say, well, we have a ternary operator. We could use it, but we wouldn’t improve on the readability:

Nil-coalescing operator, the ‘??’ operator, gives us a much shorter and readable code:

If you dive in the swift optional type, you’ll find the function definition for the ‘??’ infix operator:

The actual implementation is:

You might have noticed that the default value is actually a closure. This is an optimisation to make sure that the default parameter doesn’t get evaluated unless it’s actually used. The parameter is marked with @autoclosure which automatically wraps an argument to the function in a closure, thus removing the need for us to use the curly braces when we call the function.

map and flatMap

Value transformations are so common that we have a few functions built-in to the optional type just for this purpose. You’re probably used to seeing map and flatMap functions when working with collections, but you can also find them when working with optionals. Let’s say you wanted to use your optional to create another value of a different (or same) type, something like this:

Here we’re parsing a string into an Int and then multiplying that Int by 1.5 if it’s not nil. We can use the map function to write a shorter version of this:

As we can see, this is much shorter and more readable.

flatMap is doing pretty much the same thing as map. The only difference being that flatMap will flatten the result. Meaning, if your result is an optional optional it will be flattened to an optional. Let’s examine this on an example:

Because map was returning an optional, and we parsed a string into an Int, which also returns an optional, we get a double optional. We can easily get rid of this with a flatMap:

Now our result is nice and flattened. And this brings us to the end of this post.

Conclusion

Optionals are a crucial part of swift, and you won’t be able to escape them if you want to use the language. Understanding how they work will only make you a better developer. Last week we covered some basics on optionals that will cover most of your day-to-day development needs. But sometimes you just need a little more, I hope you learned a little bit more reading this article.

Have a nice day πŸ™‚

Dejan.

More resources

2+

Leave a Reply