Optionals in Swift

Introduction

One of the things that separate Swift from other languages is the ability to recognize optionals. Optionals in Swift allow you to have full control of your functions and variables. The main idea around optionals is that a variable or function can have two states: it can either have a value or not. The significance of this is that we can have functions return a nil instead of an arbitrary predefined value to represent a nil.

For example: Given a list of customers, return the 100th customer. What if the 100th customer doesn’t exist? We can represent the nullity by some arbitrary value, but it would make sense to return a nil instead of a predefined value.

Take this other example. Given a list of numbers, find the largest number. Without optionals, we would have to return a predefined value that would represent a non existent large number. We can represent this as -1. The problem with predefined values is that it can sometimes be the true value.

In this example, this would work if you are given an empty list. What if you are given a list of negative numbers from -10 to -1. In this case, the largest number would be -1. However, -1 is predefined as a nullity.

While these simple cases may not illustrate the full advantage of optionals, it is the elegance of handling nullity that makes your code cleaner and readable.


Best Practices

When working with optionals, it is ideal to never force-unwrap your variables unless you are 110% certain that you will never encounter an unexpected nil while unwrapping an optional error. The other exception is when creating IBOutlets because your outlets should be connected to your storyboards at all times.


Safe Unwrapping

Swift safe unwrapping features that can make your code look cool. There are two types: guard let and if let.

An if let statement takes an optional value if it exists and assigns it to a new variable and you can proceed to what you want to do with that value.

For Example


if let username = user.username {
    // If the username exists, we use it
    self.title = username
} else {
    // otherwise, we set a placeholder
    self.title = “No Username”
}  
            

A guard let statement is the opposite of an if let. A guard let allows us to break out of a function whenever a nil was caught. Otherwise, we proceed with the value that was found.

For Example


func setUsername() {
    // If the username exists, we proceed. Othese, we breakout of the function.
    guard let username = user.username else { return } 
    self.title = username
}