Swift Basics: The Why, What and How of Optionals
Tags: swift, ios
Published: 2020-02-01 14:31:51

Optionals are one of the tricky parts of Swift. Mainly because similar concept is not present in many languages and you need to understand them pretty early on to know what is going on with all these `?`, `!`, `if let` and similar in the code..

_So first things first._

## Why

Why have Optionals at all? Other languages can work without them. But they still have to deal with **absence of value**. This si super important concept. Not everything has value at all time. 

So if you are expecting number in a form of an `Int` but have no guarantee to get it. How would you represent this? `0` or `-1` can work in some context, but this can equally be a valid number.

Enter `null` value or rather `nil` which Swift uses. Those exist to represent the absence of value and you can find them in Java, C#, JavaScript, Python (in the form of `None`) and other languages.

Now you need mechanism to only access the variable if it has value and is not `nil`. This is where Optionals come in. To safely deal with absence of value.

## What

So what are Optionals? In a nutshell a way to deal with these situations where value may or may not be present. Way to safely access this value or otherwise handle its absence.

I think it is helpful to think about Optionals as kind of boxes. This box can either be empty (`nil`) or contain stuff (aka our value). Swift offers us many ways to safely (or dangerously) open that box and then work with just the value.

[Behind the scenes](https://github.com/apple/swift/blob/master/stdlib/public/core/Optional.swift) Optional is just an `enum` with two cases and special compiler support. That is all. The end result is pretty great system for dealing with uncertainty concerning the availability of values.

## How

Accessing values from Optionals is called _unwrapping_. Maybe like unwrapping a present? 🙂

### `if let`

One of the opening techniques is the `if let` construct to safely bind the value to non-optional variable. 

Suppose we have this `Int` variable:

```swift
var number: Int? = 4
```

It is of type `Optional<Int>` because instead of `4` it could contain `nil`. Swift won’t let you work with `number` as it were normal `Int` and for example do arithmetics like:

```swift
let result = number + 5 // error!
```

Because what would `nil + 5` equal to? Nothing and five as a bonus? :-)

We need to “unwrap” the value first. 

```swift
if let num = number {
		let result = num + 5 // works!
}
```

If `number` has a value, `if let` will bind it to `num` which will be available in its scope and we can use it as standard `Int`.

This is the Swift’s way of preventing runtime crashes, because some variable is `nil` and cannot be used.

### `guard let`

Very similar to `if let` but the body of the `guard` is used to handle situations when optional is `nil` and must not “fall through” which means it has to exit the current scope. Usually with `return` but you can also use `continue` or `break` when in a loop.

```swift
guard let num = number else {
		// number is nil, fallback code
		return
}
print(num) // num is no longer optional
```

Dangerous `!`

You can use `!` operator to circumvent safety and force unwrap the value. This is dangerous because if the variable is `nil` your program will crash.

```swift
let number: Int? = nil
print(number!) // crash
let number2: Int? = 3
print(number2) // prints 3
```

It is best to avoid. However `!` can be useful in situations you are 100% sure value is present. Maybe because you set the value yourself on the previous line. 

### Comparing with `nil`

You can also check optionals for value with standard `if`:

```swift
if number != nil {
		// number is still optional
}
```

###  Providing default value

There is yet another useful technique for dealing with Optionals in the form of **nil coalescing** operator `??`.

```swift
let number: Int? = nil
print(number ?? 3)
```

If the left side is `nil` the right side will be used. You can chain this but for the sake of readability I would not recommend it.

_Is anything not clear? Do you want more information? Ask in the comments and I will do my best to help you. Thanks for reading!_