Optionals

Why Optionals are useful

released Sat, 02 Mar 2019
Swift Version 5.0

Why Optionals are useful

Optionals aim to solve a problem related to something called "null pointers". We don't want to go too much into the history here, instead, we will showcase a typical situation where optionals are needed.

Imagine that you write your own User Defaults. We want to store a value String for a key String . We will ignore almost everything except for the one function get that allows us to get a String from the defaults.



struct MyDefaults {

   ...

   /// A function that returns a `String`

   func get(key: String) -> String {

   }

}


The problem is what do we do when we don't have that value in our defaults? What would we return? Now, we could return an "Empty" string, but that wouldn't be right, would it? Imagine you'd save the username in the defaults. Next time the user starts his app he'd see an empty username.

What you really want to do is express the notifion of "Nothing". We kinda want to write something like the following:

func get(key: String) -> String or Nothing {

}


This either gives us back a string or it gives us back nothing. This is fundamentally what optionals are good for. They explain to the Swift type system and to the user that a value can either be Something or Nothing. The implementation is also really simple. It is just an enum with two cases: some and none. Some, has the actual value. Here's a simplified version:

enum MyOptional {

   case some(String)

   case none

}

That's it. Now, the actual Swift Optional is not limited to Strings, instead it uses generics in order to provide support for any kind of type. It kinda looks like this:

enum Optional<Wrapped>

   case some(Wrapped)

   case none

So what do we do if we call a function that returns an optional? Since optionals are just simple enums, we can just use Swift's normal enum handling for this:

let optionalValue = functionReturningOptional()

switch optionalValue {

case .some(value): print(value)

case .none: print(\"Nothing\")

}

The types of Optionals

Thankfully, we don't have to spell out the long Optional.some all the time. Instead, Swift offers us a very brief alternative, which is just adding a questionmark ? to a type. This will tell Swift that this type is an Optional. This means that the following two are equal:

let one: Optional<Int> = Optional.some(5)

let two: Int? = 5

This is usually the default Syntax for Optionals in Swift. You'll hardly see the other Syntax, but it is still good to know as you might stumble upon it from time to time.

Also, if you want to create an empty optional, you can just use nil as a shorthand for the empty optional. Again, the following two lines are equal:

let one: Int? = Optional.none

let two: Int? = nil

You can only use nil if Swift can somehow infer the type of the Optional, so the next example does not work because Swift does not know what kind of Optional this is. Is this a Int? or a Float? or a String?. Swift can't find out:

let doesNotWork = nil

Swift offers many ways of handling Optional types. Lets look at them next.