When to use Optionals

Hi all, I want to when to use optionals. I fully understand what an optional is and how to unwrap them. What I am not fully confident about is when to use it. Every time I declare an instance I always do it like this var number = Int()

The most general guideline I can think of is: use Optionals when nil is a meaningful value.

The Swift Programming Language - Basics


You use optionals in situations where a value may be absent. An optional represents two possibilities: Either there is a value, and you can unwrap the optional to access that value, or there isn’t a value at all.


The concept of optionals doesn’t exist in C or Objective-C. The nearest thing in Objective-C is the ability to return nil from a method that would otherwise return an object, with nil meaning “the absence of a valid object.” However, this only works for objects—it doesn’t work for structures, basic C types, or enumeration values. For these types, Objective-C methods typically return a special value (such as NSNotFound) to indicate the absence of a value. This approach assumes that the method’s caller knows there’s a special value to test against and remembers to check for it. Swift’s optionals let you indicate the absence of a value for any type at all, without the need for special constants.

Here’s an example of how optionals can be used to cope with the absence of a value. Swift’s Int type has an initializer which tries to convert a String value into an Int value. However, not every string can be converted into an integer. The string "123" can be converted into the numeric value 123, but the string "hello, world" doesn’t have an obvious numeric value to convert to.

The example below uses the initializer to try to convert a String into an Int:

  1. let possibleNumber = "123"
  2. let convertedNumber = Int(possibleNumber)
  3. // convertedNumber is inferred to be of type "Int?", or "optional Int"

Because the initializer might fail, it returns an optional Int, rather than an Int. An optional Int is written as Int?, not Int. The question mark indicates that the value it contains is optional, meaning that it might contain some Int value, or it might contain no value at all. (It can’t contain anything else, such as a Bool value or a String value. It’s either an Int, or it’s nothing at all.)

The problem with nil is that it's an old-timey word that nobody uses, which was chosen for familiarity to Objective-C developers (which I would guess used it because it was a very short word, but Objective-C was known for being verbose so I don't get it). none is better because it's still used in modern speech; we maybe should deprecate nil at this point.


I'm not sure that the semantics of none work, though. Given the question, "How many scoops of ice cream does Jessy like on hot apple pie?", the answer may be 2 or none or we don't know. The virtue of nil is that's not really used for anything in modern speech.

If we want to bring the semantics of "don't know" into Swift, how about replacing nil with dunno?? (j/k, of course)


You can certainly write var number = Int() if you'd like. This will initialize number to zero. However, when you read the value of that variable later, you may have trouble distinguishing whether any zero is the meaningful result of, say, a very difficult computation or still just the placeholder you assigned initially.

If you're not ready to initialize the value where you declare the binding, you may want to consider just writing var number: Int (or let number: Int, as the case may be). You'll note that you can't read the value of a variable that hasn't first been initialized.

What is the role of Optional in all this? When dealing with real-world data, you'll often find that some values are missing. A user may choose not to fill out part of a form, for example, or you may have a list of measured values from a device where certain measurements might not have been taken.

It can be a major source of errors when you don't take into account how missing data is represented. For example, if I'm calculating the average temperature throughout the day as measured across all of my smart thermostats, I don't want missing data to be represented as 0 or as any other number, because that would skew my average unless I know to take out these fake results. To do so, however, I'd have to know what arbitrary number the smart thermostat decided to use as placeholder meaning that there's no temperature information, and critically I'd have to remember to deal with this scenario.

Internally, once I've ingested the smart thermostats' data, I can avoid having to carry on using an arbitrary number for missing data and instead represent temperatures as a list (array) of optional numbers. That way, nil can represent missing data, and Swift will remind me when I've forgotten to consider the possibility that data might be missing. For example, when I try to calculate an average, Swift will tell me that I have to unwrap each data point first and choose what to do when a data point is nil.