US & Canada: 877 849 1850
International: +1 678 648 3113

Accelebrate Blog

ACCELERATED LEARNING, CELEBRATED RESULTS

Thinking in Swift (Part III) – Optionals

The one topic that seems to present the most difficulty for developers new to the Swift programming language is the concept of optionals. The basic idea is relatively simple to understand – there has to be a way to allow for a variable to be empty (a state most languages identify as null or nil).

I think the reason most developers have trouble is because of the unique syntax and variety of shortcuts that the language provides. Another issue is that the documentation and many other articles focus almost exclusively on the mechanics and don’t spend enough time on the “why.” So, in this article, I’ll do my best to address both.

Value Types, Reference Types, and the Other Guys

Most modern compiled languages (including Java, C#, and Swift) group data types into two separate categories – value types and reference types. Value types contain their value directly while reference types contain the location to another place in memory where the actual value is stored.

The main reason for this distinction is performance. Reference types are very flexible and necessary to support many features of object-oriented programming. They are used for strings and objects. However, they require more work to deal with at runtime. Therefore, value types are better for simple things like integers and Boolean values.

This all makes sense but introduces a wrinkle – reference types can easily accommodate a variable that doesn’t have a value. The variable is simply set to null (or nil).

    Person *p = nil; // Objective-C
    Person p = null; // Java
    Person p = null; // C#

With a value type, however, you cannot do this. A value type can represent the value zero but cannot accommodate the concept of null.

    int i = nil;  // Invalid Objective-C
    int i = null; // Invalid Java
    int i = null; // Invalid C#

To address this issue, each language includes a way for a value type to be null. For each of these languages, you can accomplish this by wrapping a value type with a reference type. In the case of integers, Objective-C has NSNumber, Java has Integer, and C# has Nullable<int> (also can be written as int?). Along with each of these types, there is way to check if the wrapper has a value and a way to access the wrapped value. When Swift was developed, this issue had to be addressed yet again. So, what did the architects of Swift decide to do? Did they follow the crowd, go a completely different direction, or find some sort of middle ground? Let’s see…

Swift = Value Required

One decision the designers of Swift made was to enforce “value required” for every type of variable (value types and reference types). This is different from the other three languages we have looked at.

    var i:Int = nil    // Invalid Swift
    var p:Person = nil // Invalid Swift
    let p:Person = nil // Invalid Swift

The motivation for this rule is to allow you to write cleaner, more robust code. A very common mistake is to write code that accesses a variable without a value. This type of mistake typically causes the application to crash with a “null reference exception” or similar message. Your job (and the compiler’s job) can be made easier by guaranteeing that every variable will always have a value.

Okay, I buy that argument but I still have cases where I need a variable to represent “no value”. How does Swift provide for that?

Optionals

Swift does have an answer – it’s optionals. Any time you need a variable that can be null (value type or reference type), you can use the “?” operator to identify a variable whose value is optional. Such a variable can be set to nil to represent an absence of value.

    var i: Int? = 2
    i = nil

A variable declared as an optional is a wrapper object for the underlying variable. Therefore, you cannot directly access the wrapped value.

    var i: Int? = 2
    var j = i + 2   // compile-time error

If an optional is not given an initial value, it is automatically set to nil and you can always check for the presence of a value by comparing the optional to nil.

    if (i != nil) {
      // do something with i
    }

Forced Unwrapping

If you know an optional contains a value (maybe because you used an if statement like in the previous section) then you can obtain the value by using the “!” operator. This is known as “forced unwrapping”.

    var j = i! + 2

Note that if you try to unwrap an optional that does not have a value, an exception will be thrown (so, don’t do that).

Not too bad, right? So, to review…

  • Every variable needs to have a value.
  • If you want a variable that doesn’t need a value, use “?” to make it an optional.
  • To get the value of an optional, use “!” to unwrap it. Of course, make sure to check that it has a value before you do that.

There is, however, quite a bit more to the story and this is the point where people start to get confused. So, I’ll do my best to make sure that doesn’t happen.

Optional Binding

From the previous two sections, you may be thinking, “Wow, this seems really painful. If I want to get the value of an optional, I always have to check its value with an if statement and then unwrap it?” Fortunately, Swift provides a few features that help to ease the pain – the first is “optional binding”.

With optional binding, you can conditionally assign the unwrapped value to a temporary variable:

    if let v = i {
      // do something with v
    }

In the code above, there are two possibilities – the optional variable i either has a value or it doesn’t. If it does, then v gets set to that value and the code block executes. If i doesn’t have a value then nothing happens (unless you add an else block). Optional binding can be especially useful when calling a function that returns an optional. In that case, you probably only want to do something if a value comes back.

Optional Chaining

For this next feature, let’s setup an example. Let’s say we have an object of type Customer. A customer may or may not have a sales representative assigned. So, we define the salesRep property of Customer to be an optional.

    class Customer {
      var salesRep: Person?
    }

At some point during the run of our application, we need to display the name of a customer’s sales representative. How can we do this? First of all, the following code will not compile:

    let name = cust.salesRep.name // compile error

Because salesRep is an optional, it must be unwrapped in order to retrieve the value. So, one option that may work is to use forced unwrapping:

    let name = cust.salesRep!.name
    println("Sales rep is: \(name)")

The problem here is that a runtime error will occur if salesRep is nil. So, another option would be to check the value first or use the feature we just learned about – optional binding:

    if let rep = cust.salesRep {
      println("Sales rep is: \(rep.name)")
    }

Optional chaining allows us to write this a little differently:

    if let name = cust.salesRep?.name {
      println("Sales rep is: \(name)")
    }

Notice the use of the question mark to perform the unwrapping. In this case, you are basically telling Swift “Unwrap this variable unless it’s nil. If it’s nil then just stop and forget about the rest.” That way, you can chain multiple optionals together:

    if let zipCode = cust.salesRep?.address?.zipCode {
      // only executes if customer has a sales rep
      // and that salesRep has an address
    }

Implicitly Unwrapped Optionals

We have arrived at the final Swift feature we are going to talk about in this article – implicitly unwrapped optionals. Sounds impressive, doesn’t it? For this one, let’s setup another example scenario.

Imagine you have a controller object that has variables that point to user interface elements (e.g. a button or a text field). These variables have to be declared as optionals because the elements aren’t there yet when the controller is first created.

    class MyController {
      var myButton: Button?
      var myTextField: TextField?
    }

However, a short time after the controller is created, those elements get set by something else. Then, once they’re set, they will always have a value (guaranteed). So, in other words, it is clear from the way the application is structured that every time you attempt to access these variables, they will always have a value. Unfortunately, you will still have to use an exclamation mark to perform forced unwrapping every time you access one of these variables.

     myButton!.text = "Hello"

Xcode will complain every time you forget to put that exclamation mark there and you will say “But I know the value is there! What a pain! And it looks ugly!” My guess is that a developer on the Swift team had the same experience and so they added the ability to make this situation less painful. You can declare the instance variables as implicitly unwrapped optionals like so:

    class MyController {
      var myButton: Button!
      var myTextField: TextField!
    }

By doing this, you are effectively telling Swift to automatically unwrap the variable whenever you attempt to use it.

    myButton.text = "Goodbye"

Much better. Just remember that you have to be absolutely sure that the variable will never be nil. This is true for controllers and views but may not be in other situations.

Conclusion

As you have seen, the Swift designers sure did get a lot of mileage out of “?” and “!”. If you are new to Swift, you most likely will have many moments of frustration until you get comfortable with optionals. During that process, try to remember these tips:

  • When you need a variable, make it a constant.
  • If it can’t be a constant, make it require a value (the default).
  • If it needs to possibly be nil, make it an optional.
  • When using an optional, program defensively – what if it’s nil?
  • If you know if will never be nil when you’re using it, maybe it should be an implicitly unwrapped optional (or maybe it shouldn’t be an optional at all).

Author: Jason Bell, Accelebrate’s Director of Technology and senior instructor.

Accelebrate offers private Swift training and iOS training and for groups and instructor-led online Swift classes for individuals.

Categories: Mobile Development Articles
Tags: , , , ,

7 Responses to "Thinking in Swift (Part III) – Optionals"

Leave a Reply to Antonio Cancel reply

Your email address will not be published. Required fields are marked *

Your email address will not be published. Required fields are marked *

*



You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Please contact us for GSA pricing.
Contract #GS-35F-0307T

Please see our complete list of
Microsoft Official Courses