Comparison and logic
Besides counting, Swift's calculator answers yes-or-no questions. Is one number larger than another? Do two strings match? The answer is a value of type Bool: true or false. You will need such answers as soon as a program starts choosing what to do next.
Six comparison operators
A comparison operator takes two values and returns a Bool:
==means equal;!=means not equal;<and>mean less than and greater than;<=and>=mean less than or equal, greater than or equal.
let age = 17
print(age >= 18) // false
print(age == 17, age != 17) // true false
let isAdult = age >= 18
print(isAdult) // falseLet's go line by line:
age >= 18asks whether the age has reached 18. The answer isfalse.age == 17givestrue, andage != 17givesfalse.- The result of a comparison can be stored in a constant:
isAdultholdsfalse.
A single = puts a value into a constant or a variable, while a double == compares. A name for a Bool usually reads as a statement: isAdult, hasTicket.
Logical operators
Picture a bouncer at the door of a club. He lets a guest in if the guest is 18 and has a ticket. A guest on the VIP list gets in without a ticket. To write such rules, conditions are combined with logical operators.
let hasTicket = true
let isVip = false
print(isAdult && hasTicket) // false
print(isVip || hasTicket) // true
print(!isVip) // trueAND: &&
a && b gives true only when both parts are true. The guest has a ticket but is 17, so isAdult && hasTicket is false.
OR: ||
a || b gives true when at least one part is true. The guest is not on the VIP list but has a ticket, so isVip || hasTicket is true.
NOT: !
!a flips the answer. isVip is false, so !isVip is true.
The right side may not run
Once the bouncer sees that a guest is under 18, he no longer asks for a ticket: the answer "no" is already known. Swift does the same. If the left side of && is false, the right side is not evaluated at all. With || it is the other way round: when the left side is true, Swift skips the right side. This is called short-circuit evaluation.
Short-circuit evaluation protects against dividing by zero. Dividing a whole number by zero at run time crashes the program, and a check to the left of && keeps the division from running:
let total = 10
let count = 0
let isBig = count > 0 && total / count > 2
print(isBig) // falsecount > 0isfalse, sincecountis zero.- The answer of
&&is already known, sototal / countis not evaluated. - The program prints
falseand does not crash.
Here the bouncer picture is inaccurate: a real bouncer might still ask for the ticket of someone he has already turned away. In that case Swift never evaluates the right side, and that is what the protection against dividing by zero rests on.
Short-circuit evaluation comes up often in interviews. The usual question is whether the right side of && runs when the left side is false.
Comparing strings
Strings can be compared too. The == operator checks that two strings match character for character. The < and > operators compare strings from the left by character numbers: every character has its own number in the computer. The smaller string is the one whose first differing character has the smaller number. For lowercase Latin letters this matches dictionary order; in other cases it may not:
"кот" == "Кот"isfalse: an uppercase letter and a lowercase one are different."apple" < "banana"istrue: the first letteracomes beforeb."Zebra" < "apple"istruetoo: the uppercaseZhas a smaller number than the lowercasea."10" < "9"istrue: strings are compared character by character, not as numbers, and1has a smaller number than9."ёж" < "жук"isfalse: the letterёhas a larger number thanж, and even larger thanя.
Common mistake
The check for zero is placed to the right of the division:
let total = 10
let count = 0
let isBig = total / count > 2 && count > 0 // ✗
print(isBig)Fatal error: Division by zeroThe left side of && is evaluated first, and dividing by zero crashes the program before the check is reached. A check that protects an action must stand to the left of &&.
Key points
- The operators
==,!=,<,>,<=and>=compare two values and give aBool. &&givestrueonly when both parts are true,||when at least one is, and!flips the answer.- If the left side of
&&or||already settles the answer, the right side is not evaluated. - Strings are compared character by character:
"Zebra" < "apple"and"10" < "9"are bothtrue.