Decisions with if and switch
Choosing a path with if and else, sorting many answers with switch, and matching ranges of numbers.
Asking a question
An if runs a block only when a condition is true. The condition is a question with a Bool answer, such as score >= 80. Brackets around the condition are not needed, but the curly braces around the block are required.
Add an else for the other case. A chain of else if checks answers in order, and the first true one wins, so the order of the questions is part of your meaning.
Order decides the answer. A score of 85 tested against >= 90 first falls through to >= 80 and prints grade B. Put >= 70 above >= 80 and the same score prints grade C, because the first true branch wins and the rest are never asked. When a chain gives a surprising grade, read the conditions from the top and stop at the first one that is true.
switch, when there are many answers
A switch compares one value against several case labels. Each case ends where the next begins, so there is no fall-through and no break to remember.
The cases must cover every possibility. For a whole number that means a default, and for an enum that means every case, which the compiler checks for you.
A switch works on strings and characters as well as numbers. case "north", "south": lists two values in one arm, and the comparison is exact, including case. There is no fall-through from one case to the next, so an arm ends when its block ends; fallthrough exists but is rare, and reaching for it usually means the cases should be combined.
Matching ranges and a quick choice
A case can be a range, so case 1...5 matches any number from one to five. This reads closer to the way you would say it out loud than a pile of comparisons.
The short form, question ? a : b, picks between two values in one line. Use it for small choices, and reach for if when the branches do real work.
A range can be open at one end. case ..<0: catches every negative number and case 100...: catches everything from one hundred upward, which is how a switch covers a number line without listing values. A where clause adds a condition to a case: case let n where n % 2 == 0: matches only the even values that reached that arm.
Every condition is a Bool
Swift has no notion of a truthy number or a truthy string. The thing between if and the opening brace must be a Bool, and a comparison is the usual way to make one. if count is an error; if count > 0 says what you mean.
The operators && and || stop as soon as the answer is known. That short-circuit is why if index < items.count && items[index] > 0 is safe: when the first test is false, the second one never runs.
The same short-circuit makes a guard against nil safe: check for nil first, then use the value.
Short-circuiting is not just an optimisation; it is part of the meaning. if user != nil && user!.age >= 18 is safe because the second test is never reached when the first is false. Swap the two tests and the same line can crash. Whenever one condition protects another, the protecting test belongs on the left.
The ! operator reverses a Bool, so if !items.isEmpty reads as “if there are items”. It binds tightly, so !a && b means (!a) && b. A double negation is legal and almost always a sign that the condition should be rewritten in the positive.
Two ways to branch
let score = 82
if score >= 90 {
print("grade A")
} else if score >= 80 {
print("grade B")
} else {
print("keep going")
}
switch score {
case 90...100:
print("top band")
case 80..<90:
print("middle band")
default:
print("low band")
}Three mistakes decide the wrong branch. A condition must be a Bool, so if score will not compile. A single = assigns and is not allowed in a condition, while == compares. A switch over a number needs a default unless the cases cover every value, and the first matching case wins, so put narrow ranges before wide ones.
A grade, a day and a size
Run it and read which branch each value took. Then change the score so a different grade prints, and predict the output before you run it again.
Try these next
- Write a grade chain for five bands and test a score at each boundary.
- Replace an
ifchain with aswitchand check that every band still prints the same word. - Use a ternary to choose between two labels, then rewrite it as an
ifand compare which reads better.
A ticket price for one visitor
Run it, then change the age and the member flag. Predict the price and the message before each run, and check which branch produced them.
A switch must be able to finish. If you leave out a default, the compiler will complain when the cases cannot cover every value, which is its way of asking what should happen next.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
With a chain of else if, which branch runs?
