Embracing Optionals In Swift

Embracing Optionals In Swift

Type safety is a fundamental concept of the Swift programming language and optionals neatly tie into Swift's strict type safety rules. The concept underlying optionals is simple, an optional has a value or it does not.

Developers new to this concept often struggle with optionals. They see optionals as an obstacle and a direct consequence of the strict type safety rules imposed by the language. This struggle usually dissipates after spending some time with the language and after discovering Swift's constructs for safely interacting with optionals, such as optional binding and optional chaining.

Warning Sign

Before the struggle ends, though, brute force is used to attack the problem that optionals appear to be. After discovering the exclamation mark, every optional is considered a nail that needs to be hit with the proverbial hammer. Forced and implicitly unwrapped optionals are temporarily seen as the solution to the problem.

The exclamation mark is in Swift what you may intuitively expect it to be, a warning sign. If you use the exclamation mark, you are about to perform an operation that may backfire. Force unwrapping an optional that does not contain a value throws a runtime error, crashing your application. The exclamation mark warned you this could happen, though.

Elegance & Beauty

The beauty of optionals is easily overlooked if not paid attention to. Optionals embody a concept that is easy to grasp. And that is what makes them powerful. If you are given a non-optional, you are given the promise that it has a value, it is anything but nil. In computing, that is a bold promise.

If you know that a constant or variable is guaranteed to have a value, you are also given freedom.

If you know that a constant or variable is guaranteed to have a value, you are also given freedom. A pointer in Objective-C, for example, is not guaranteed to be not nil. While it may be pointing to a valid object now, that may change later. No problem. You can safely send messages to nil in Objective-C. That is wonderful, but how often has this been an advantage. If you are sending a message to nil, it probably means that you were expecting something to happen that didn't happen. Is that a better solution than optionals?

If you are sending a message to nil, it probably means that you were expecting something to happen that didn't happen.

Swift to the Rescue

Swift doesn't leave developers out in the cold. The language offers a number of constructs for working with optionals, such as optional binding and optional chaining.

Optional binding is used to safely unwrap the value that is stored in an optional. If the optional has a value, then that value is bound to a constant that is available in the if clause.

if let message = message {
    print(message)
} else {
    print("no value")
}

This solution is more elegant than verifying whether message has a value and then force unwrapping the optional using the exclamation mark.

if message != nil {
    print(message!)
} else {
    print("no value")
}

Optional binding is flexible and powerful. Take a look at the following example.

if let payload = payload,
   let message = payload["message"] {
    print(message)
}

Optional chaining is an elegant alternative to force unwrapping optionals. Instead of force unwrapping an optional, you use optional chaining to access a property or invoke a method on the value stored in the optional.

label?.textColor = UIColor.blackColor()

The textColor property is only set if label, an optional, has a value. The question mark is used to safely set the textColor property through optional chaining.

Embrace Optionals

Even though it may seem as if optionals are a solution to work around Swift's strict type safety rules, they are complementing those rules. Optionals get rid of unsafe pointers and offer guarantees that make your code safer and easier to debug.

Optionals get rid of unsafe pointers and offer guarantees that make your code safer and easier to debug.

While it may seem great that you can send messages to nil in Objective-C, it is an empty promise. If you consider your application not crashing when you send a message to a nil pointer, then think again. Also consider that optionals can be used for any type while nil only applies to pointers in Objective-C.

If you are serious about Swift, then it is important that you become familiar with optionals, which problems they solve, and embrace them in the code you write.