Unwrapping optionals

So far, we know that optionals wrap values in themselves. Wrapping means that the actual data is stored within an outer structure.

For instance, we print optionalString as follows:

print(optionalString)

The result will be Optional("A String literal").

How will we unwrap optionals and use the values that we need? There are different methods to unwrap optionals that we will go through in the following sections.

Force unwrapping

To unwrap optionals, the easiest and most dangerous method that we can use is force unwrapping. In short, ! can be used to force unwrap the value from Optional.

The following example forcefully unwraps optionalString:

optionalString = "An optional String"
print(optionalString!)

Force unwrapping the optionals may cause errors if the optional does not have a value, so it is not recommended to use this approach as it is very hard to be sure if we are going to have values in optionals in different circumstances.

In fact, force unwrapping eliminates the benefits of type safety and may cause our applications to crash during runtime.

nil checking

Force unwrapping an Optional could crash our applications; to eliminate the crashing problem, we can check whether the variable is not nil before unwrapping it.

The following example presents a simple nil checking approach:

if optionalString != nil {
    print(optionalString!)
}

This approach is safe in compile and runtime but may cause problems during editing. For instance, if we accidentally move the print line outside the if block, the compiler is not going to complain and it may crash our application during runtime.

Optional binding

The better approach would be to use the Optional binding technique to find out whether an Optional contains a value or not. If it contains a value, we will be able to unwrap it and put it into a temporary constant or variable.

The following example presents optional binding:

let nilName: String? = nil
if let familyName = nilName {
    greetingfamilyName = "Hello, Mr. (familyName)"
} else {
    // Optional does not have a value
}

The if let familyName = nilName statement will assign the Optional value to a new variable named familyName. The right-hand side of the assignment has to be an Optional, otherwise, the compiler will issue an error. Also, this approach ensures that we are using the unwrapped temporary version so it is safe.

This approach is also called if-let binding and is useful to unwrap Optionals and access the underlying values, but if we get into a complex structure of nested objects such as a JSON payload, the syntax becomes cumbersome.

We will need to have lots of nested if-let expressions in these cases:

let dict = ["One": 1, "Two": 2, "Three": 3]

if let firstValue = dict["One"] {
    if let secondValue = dict["Two"] {
        if let thirdValue = dict["Three"] {
            // Do something with three values
        }
    }
}

To overcome this issue, we can use multiple Optional bindings as follows:

if let
firstValue = dict["One"],
secondValue = dict["Two"],
thirdValue = dict["Three"] {
    // Do something with three values
}

This syntax makes the code more readable but still is not the best approach when we need to bind multiple levels of optionals. In the following sections, we will look at different methods to further improve the readability and maintainability of our optional handlings.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset