if let
Comparing with nil tells you whether the box is empty, but it does not open it. To use the gift, you open the box. If there is something inside, you take the gift out and work with it, and if it is empty, you do something else. In Swift, if let opens an optional this way:
let typed = "25"
if let age = Int(typed) {
print("next year:", age + 1) // next year: 26
} else {
print("not a number")
}Let's go through the program line by line:
Int(typed)turns the text into anInt?, and this box holds25.if let age = …opens the box. There is a number inside, so Swift creates a constantageof typeIntwith the value25and runs the block in braces.ageis an ordinary whole number, andage + 1adds up without an error: the program printsnext year: 26.- The program skips the
elsebranch.
If you replace "25" with "abc", the box turns out empty. Then the constant age does not appear, the first block does not run, and else prints not a number.
How the syntax works
This check is called optional binding: the value from the box is bound to a new name. The line if let age = Int(typed) has three parts:
if let—"if there is something in the box, take it out";age—the name for the value from the box;= Int(typed)—the optional being opened.
if let has three rules:
- the block in braces runs only when the box holds a value;
- the name
ageexists only inside these braces, and after}it is gone; - the
elsebranch runs when the box holdsnil, and you may leave it out.
In the program below, the result of Int(…) is first stored in a constant, so that you see the box apart from its contents. Press "Next step" and watch the constant n: it appears only inside the braces and only when the box holds a number.
1let first = Int("12")2if let n = first {3 print(n + 1)4} else {5 print("not a number")6}7let second = Int("12a")8if let n = second {9 print(n + 1)10} else {11 print("not a number")12}13print("done")
The text holds a number, so first is a box with 12 inside.
The widget showed when the constant n exists and when it does not:
- with a number in the box,
if letcreates the constantnand runs the first block; - with
nil, no constant appears, and theelsebranch runs; - after the closing brace,
nis gone in both cases.
Here the box picture is off. You take a real gift out of its box, and the box becomes empty. But if let copies the value into a new constant: first holds Optional(12) to the end of the program.
In interviews, if let is called safe unwrapping. The program cannot crash on such a check: on nil it skips the block and runs else, if there is one.
Other forms of if let
The short form
If the optional already has a name, you do not have to repeat it. The line if let score means the same as if let score = score:
let score: Int? = 90
if let score {
print("score:", score) // score: 90
}Inside the braces, score is already the number 90 of type Int. Outside the braces, the same name means the optional Int? again.
Two optionals at once
One if can open several boxes, separated by commas. The first block runs only if every box holds a value:
let width = Int("4")
let height = Int("five")
if let width, let height {
print("area:", width * height)
} else {
print("need two numbers") // need two numbers
}The text "five" holds no number, so height is empty. One empty box is enough to send the program to the else branch.
Common mistake
The name from if let was used after the closing brace:
if let age = Int(typed) {
print(age)
}
print(age + 1) // ✗error: cannot find 'age' in scopeThe constant age exists only inside the braces of if let, so in the last line there is no such name. Write the code that needs the value inside those braces.
Key points
if let age = Int(typed)opens an optional: if it holds a value, it creates the constantageand runs the block.- On
nilthe block does not run, and theelsebranch, if there is one, does. - The name from
if letexists only inside the braces, and the optional itself does not change after the check. - The short form
if let scoreopens an optional with the same name, and commas open several optionals at once.