Optionals
On May 5, 2018 by SwiftBanditLet’s Introduce the nil:
All the prior variables and constants had concrete values, they all had a value you can refer to.
But sometimes, it is useful to have an absence of a value. Let’s say you have a user in your app, and the details of this user include name, age, gender all of which are given we should have, but what about if a user does not have a phone number or email and you would like to have such a variable even if it doesn’t yet contain any value. This is what optionals are useful for.
Sentinel values is the condition in which there is an absence of a value.
Finally, Introducing Optionals:
Optionals handle the possibility of having a variable that can have the absence of a value.
- Nil is the absence of a value.
- Optionals can contain a value or possibility of a nil value. (absence of a value)
- It’s easier to understand optionals as being wrapped in mystery box, it can contain something, or it can contain nil.
- Optionals can be any type. (Int, Double, String, float, Tuples, Arrays)
To declare an Optional
1 2 3 4 5 6 |
//Declaring an Optional var name: String? var age: Int? = nil var grade: Double? = nil //All of the above are declarations of Optionals, simply place a "?" mark after the type. |
You can set a value to optionals as above, or simply set nil.
Unwrapping the Optionals:
You can unwrap optionals in various ways by force (when you know there is a value…) , optional binding, in functions using a guard statement, and nil coalescing.
If you try to print an optional, you will simply get a wrapped optional like below, the value surrounded by the Optional() function.
Attempting to mutate or operate on the optional without unwrapping it firstly will cause an error at compile time.
1 |
Value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?' |
1 2 3 4 5 |
//some code var age: Int? = 30 print(age) //Optional(30) |
Force unwrapping:
You can force unwrap an optional simply by using the “!” exclamation point.
- This will forcefully unwrap the optional and return the value inside.
- The exclamation mark tells the compiler you want to look inside the box.
- It will search inside and grab the optional value for you to use.
- If there is no value you will get a fatal error and the app will crash.
- You can use an if statement as the example below to avoid these errors in force unwrapping.
-
1fatal error: unexpectedly found nil while unwrapping an Optional value.
- The exclamation mark tells the compiler you want to look inside the box.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//force unwrapp var unwrappedAge = age! print(age) //30 //Avoid error while Force Unwrapping if unwrappedAge = age! { print(age) } else { print("There is no age in the box") } //30 //If the value is nil, it will simply run the else statement and not produce an error. |
Optional binding:
Optional binding allows you to safely access the value inside the optional.
- To use optional binding you simply use an if let statement, which will allow you access to the value if there is a value inside the Optional.
- If let doesn’t need the ‘!’ exclamation mark if the Optional is not wrapped multiple times, if it is indeed you will need to use an exclamation mark on the value of variable being set (in this case age!) like so for nested Optionals for each box/optional to unwrap.
- You can unwrap multiple values using optional binding. (example below.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//Optional Binding if let unwrappedAge = age { print(age) } else { print("There is no age value.") } //Multiple values if let unwrappedAge = age, let unwrappedName = name, age > 21 { print("You are \(name), your age is \(age), and you are obviously over 21.") } else { print("No age or name, or younger than 21") } //The above if let statement won't run unless, there is an age, name, and the age of the user is over 21 years old. |
Let’s Introduce the guard:
You can unwrap optionals using the guard statement within functions, these are helpful in apps, as user input can vary and it can come in handy when handling user input and the lack of it. The function must accept a parameter of Optional in the function declaration.
You can declare a guard statement within a function using the guard keyword.
1 2 3 4 5 6 7 8 9 |
//Functions using the guard statement def printAge(age: Int?) -> String { guard let myAge = age else { return "There is no age to print out." } return "My age is \(age)" } //If your age is nil it will return the print statement inside the else statement, if it holds a value it will return the age. |
Nil coalescing:
There is one last way to deal with optionals, and that is nil coalescing, and this allows you to set a value in the case that the value of the optional is nil.
- Therefore if you have an nil age variable, it can set a default age, based on the default age you specify in the nil coalescing statement.
- nil coalescing is performed using the ‘??’ double question mark. (see example below)
1 2 3 4 5 6 7 8 9 |
//Let's print some age. var age: Int? = nil var mustHaveAge = age ?? 0 //0 //change age variable to 21 and unwrap again. age = 21 age ?? 32 //21 |
Leave a Reply