Testing more than one thing
Sometimes a single comparison isn't enough. You may want to go to the beach only if it is sunny and hot. The logical and operator && joins two Boolean conditions and gives true only when both are true.
10 == 10 && 7 < 10 // true
Here 10 == 10 is true and 7 < 10 is true, so the whole expression is true. If either side were false, the result would be false.
| Left | Right | Left && Right |
|---|---|---|
true | true | true |
true | false | false |
false | true | false |
false | false | false |
Inside an if statement
var x = 10
if (x != 7 && 12 < x) {
println("This is true!")
}
With x equal to 10, x != 7 is true but 12 < x is false. One false side makes the whole condition false, so the block is skipped and nothing is printed.
Scala details
- Comparisons bind tighter than
&&. Inweather == "sunny" && temperature > 85, each comparison is evaluated first and then the results are combined. You don't need extra parentheses, though they never hurt. - It short-circuits. If the left side is false, Scala doesn't evaluate the right side at all, since the answer is already known. A call on the right with a side effect, such as a print, doesn't run when the left is false.
- Both sides must be
Boolean. Writingx && 5with anIntdoesn't compile. &&, notand. Scala has no keywordand. A single&exists too, but it is the non-short-circuit form for Booleans and bitwise and for integers, so use&&in conditions.- String equality uses
==. In Scala,==compares the text of two strings, soweather == "sunny"does what it appears to do.
and versus nested ifs
Two conditions that must both hold can also be written as one if inside another. That is longer, and the else case then has to be written twice:
if (weather == "sunny") {
if (temperature > 85) {
println("Going to the beach")
}
}
The version with && says the same thing in one line, and a single else then covers every case in which either check fails. Prefer && when both checks lead to the same outcome.
The exercise
The starter code declares two values:
val weather = "rainy"
val temperature = 90
The task has two steps.
- Join both checks with
&&. The weather must equal"sunny"and the temperature must be greater than 85. Print"Going to the beach"inside theif, so it appears only when both checks pass. - Add an
else. It prints"Learning to code", so the program still responds when either check fails.
val weather = "rainy"
val temperature = 90
if (weather == "sunny" && temperature > 85) {
println("Going to the beach")
} else {
println("Learning to code")
}
The temperature of 90 passes its check, but "rainy" == "sunny" is false. The whole condition is false and the program prints Learning to code. If you change weather to "sunny", both checks pass, and it prints Going to the beach. A sunny day with a temperature of 85 also prints Learning to code, because 85 is not greater than 85.
Common mistakes
- A single
&. It compiles for Booleans but doesn't short-circuit. Use&&. - Writing a shortcut such as
weather == "sunny" && > 85. Each side of&&must be a complete condition, so repeattemperature. - Misjudging the boundary.
> 85excludes 85 itself. Use>=when the value should count. - Different capitalization.
"Sunny"is not equal to"sunny".
Key takeaways
a && bis true only when bothaandbare true.- Each side must be a complete Boolean expression.
- The right side isn't evaluated when the left side is false.
- An
elsecovers every case where at least one check fails.
