Optional of an Optional

Software Engineer
Search for a command to run...

Software Engineer
No comments yet. Be the first to comment.
Introduction Last week, the Swift for Android working group announced that Swift now supports Android. This is an exciting milestone for developers who want to leverage Swift's powerful features in Android development. To help developers explore this...

In my previous article, I introduced the Swift Android Gradle Plugin that simplifies integrating Swift code into Android projects. To demonstrate the plugin in action, I built a sample Android app that generates fractal images using Swift and renders...

Taking Flight with Android XR: Building a Jetliner Demo I spent the last few days exploring Android XR, Google's latest platform for extended reality applications. After working through the documentation and experimenting with the SDK, I built a demo...

This article shows you how to eliminate the rebuild-test cycle when working with Android preferences. Pref Editor lets you modify values instantly.

The Iterator design pattern is a well-known and often-used pattern. It allows us to access elements in a collection without the need to know about the underlying storage details. We get this functionality from an object known as an iterator of the co...

During a recent debugging session, I came across an Optional of an Optional of an entity. 😱 Well, I've read about this in theory but experiencing it in practice is definitely interesting. Intro first.
Optional is a (generic) type that is used to represent the presence or absence of a value. Here's its declaration:
@frozen
public enum Optional<Wrapped>: ExpressibleByNilLiteral {
/// The absence of a value.
case none
/// The presence of a value, stored as `Wrapped`.
case some(Wrapped)
...
}
I've left out some method definitions in the type such as
map,flatMapetc along with a couple of its extensions.
@frozen is a Swift attribute that guarantees no further cases will be added (removed or reordered) on the enum declaration (This facilitates some compiler optimizations and allows a user to perform an exhaustive matching on the cases with no need for a default/'unknown' case check. For more info, check out this and this Swift Evolution proposal).
Wrapped is the generic type to be wrapped by the Optional.
ExpressibleByNilLiteral conformance denotes that this type that can be initialized using the nil literal, nil.
Before continuing with our discussion, it's important to mention that the Optional type gets some extra compiler love:
?) on a type is treated as an Optional wrapping that type. This eases reading and writing Optionals in code. For instance, the following two declarations are the same.--> let optionalString: Optional<String> = nil
--> let optionalString: String? = nil
If let, while let, guard statements can evaluate the Optional and control program flow based on the presence or absence of the wrapped value.optionalString?.removeAll() does nothing if optionalString is nil.Wrapped conforms to Equatable) promotes the non-optional value to an optional to make the types e.g. nonOptionalString == optionalString works out of the box.These and many other nifty 'tricks' make working with Optional beautiful in Swift.
Being a generic, Optional can thus be over any type including another Optional something like Optional<Optional<String>> aka String??.
Take an example of the following declaration. What's the type of languages?
let languages = ["Swift", "Kotlin", nil, "Rust"]
A quick glance would yield an assumption of Array<Any> but on closer inspection, we note that it's intuitive for the compiler to infer Array<Optional<String>> aka Array<String?> of which it does.
What's the type of first here let first = languages.first?
Now you've got it. It's a Optional<Optional<String>>.
Here's my attempt to explain. An element of the languages array is an Optional wrapping a string. The first property of an array (declared as public var first: Element? { get }) yields an Optional wrapping the Element -- the single type held by the array. In our case, it's an Optional wrapping a String and hence we get Optional<Optional<String>> 🤯!
Therefore, in the snippet below, you need to be aware that print is working with an Optional<String> (from reasons mentioned so far).
guard let first = languages.first else { return }
print(first)
In many cases, the compiler will emit warnings and offer fixes such as:

or subtle ones like the following (NB: self.deserializeEntity(from:) returns a T?):

And there you have it. Optionals make representing absence of a thing intuitive in Swift and have many uses such as in collections to denote a sentinel value when retrieving an element or during iteration. Being a generic, Optionals can be over any type including a couple of optionals such as String????? -- which is the valid, rather unuseful, type: Optional<Optional<Optional<Optional<Optional<String>>>>>.
Anyways. You get the idea. 🙈
let signOut: String? = "Happy Coding!"
print(signOut!)