More than two outcomes
A single if with an else splits the program into two paths. When you need three, four or more outcomes, you chain extra tests with else if. Swift checks the conditions from top to bottom and runs the body of the first one that is true. Every later branch is skipped, and its condition isn't even evaluated.
let language = "Python"
if language == "JavaScript" {
print("It's super popular!")
} else if language == "Python" {
print("It's so simple!")
} else if language == "Java" {
print("It's pretty hardcore!")
} else {
print("It's exotic!")
}
Here language == "JavaScript" is false, so Swift moves on. language == "Python" is true, so the program prints It's so simple! and leaves the chain. The final else has no condition. It catches everything the earlier tests did not match, so with "Go" the program would print It's exotic!.
In Swift, the conditions need no parentheses, and the braces are always required, even for a one-line body.
Order matters
Because the first matching branch wins, the order of the tests decides the behaviour. When the tests are ranges of numbers, put them in order from the lowest limit to the highest. Each else if then only needs an upper bound, because every smaller value was handled by a branch above it.
The exercise, step by step
The lesson defines a grade constant and asks for four messages:
| Grade | Message |
|---|---|
| below 5 | Failed the test |
| 5 to 7 | Passed the test |
| 8 to 9 | Good Job |
| above 9 | Perfect |
- Start with the failing grades. An
if grade < 5prints"Failed the test". Everything that reaches the next branch is therefore at least 5. - Add the middle branches.
else if grade <= 7prints"Passed the test". It needs no lower bound, because grades below 5 never get here. Thenelse if grade <= 9prints"Good Job". "Up to 7" and "up to 9" include those values, so the comparison is<=. - Finish with else. Whatever is left is above 9, so a plain
elseprints"Perfect".
let grade = 8
if grade < 5 {
print("Failed the test")
} else if grade <= 7 {
print("Passed the test")
} else if grade <= 9 {
print("Good Job")
} else {
print("Perfect")
}
With grade = 8, the first test is false (8 is not below 5), the second is false (8 is above 7), and the third is true, so the program prints Good Job. The last branch is never reached.
Testing the boundaries
Changing grade to each of these values gives the following output:
| grade | Output |
|---|---|
| 3 | Failed the test |
| 5 | Passed the test |
| 7 | Passed the test |
| 8 | Good Job |
| 9 | Good Job |
| 10 | Perfect |
Values at the edges (4, 5, 7, 8 and 9) are the ones most likely to expose a wrong comparison.
Common mistakes
- Writing separate ifs. If the second and third tests start with
ifinstead ofelse if, each test runs on its own. A grade of 4 would printFailed the testand then alsoPassed the test, because 4 is at most 7. - Putting the tests in the wrong order. If
grade <= 9came first, every grade up to 9 would printGood Job, and the later branches would never run. - Using < where <= is needed. With
grade < 7, a grade of 7 would fall through toGood Job. - Writing a condition on else. A final
elsenever takes one; if you need a test, useelse if.
Key takeaways
- A chain runs at most one branch: the first whose condition is true.
- List the tests in a deliberate order, and let later branches rely on what the earlier ones ruled out.
- A closing
elsehandles everything left over. - Test the values on both sides of each boundary.
