if / else — making decisions
Until now your programs have run straight down the page. if is where they start to choose — checking a condition and taking one path or the other. It is also, in Kotlin, something that can hand back a value.
A program that always does the same thing is a list
Everything you have written so far runs top to bottom, every time, no matter what. That is useful for a shopping list and useless for an app.
Real apps decide. If the password is right, let them in. If the score beats the record, show the fireworks. If there are no notes yet, show "nothing here yet" instead of an empty white screen.
One keyword does all of it.
1if (score > 100) {
2 println("New record!")
3}Read it as an English sentence, because it almost is one: if this is true, then do the things in the brackets. If it is not true, skip them entirely.
Picture a path through a wood that splits in two, with a sign at the fork:
Wet weather? Go left. Otherwise go right.
Three things are worth noticing about that sign, and all three are true of in code.
First, the question has exactly two answers. It is wet or it is not. There is no "sort of".
Second, you take one path or the other — never both, never neither.
Third, the paths join up again further on. Whichever way you went, you carry on with the rest of the walk afterwards.
Asking a question
The bit in the round brackets is called the , and it must produce a — true or false. Nothing else will do. You build one with a :
| Operator | Asks |
|---|---|
> | Is the left bigger? |
< | Is the left smaller? |
>= | Bigger than or equal to? |
<= | Smaller than or equal to? |
== | Are they the same? |
!= | Are they different? |
The one that catches everybody is ==. One equals sign means "put this value into that name". Two means "are these the same?". Kotlin will not let you confuse them — writing if (x = 5) gives Assignments are not expressions, which is Kotlin saying "that line stores something, it does not ask anything".
The other path
if on its own does something or nothing. Add and you get a genuine fork:
1if (age >= 18) {
2 println("Come in")
3} else {
4 println("Not tonight")
5}Exactly one of those two lines runs. Never both.
For more than two paths, chain with else if:
1if (score >= 90) {
2 println("Gold")
3} else if (score >= 60) {
4 println("Silver")
5} else {
6 println("Try again")
7}Kotlin checks the conditions in order and stops at the first one that is true. That matters more than it looks. With a score of 95 the first branch wins and the second is never even looked at — which is exactly why the tests are written biggest-first. Swap them round and every score above 60 would come out Silver.
Combining questions
Sometimes one test is not enough. Three join them up:
&&means and — true only when both sides are true.||means or — true when at least one side is true.!means not — it flips true to false and false to true.
1val age = 15
2if (age >= 13 && age <= 19) {
3 println("Teenager")
4}
5if (age < 13 || age > 19) {
6 println("Not a teenager")
7}Two tips that save real time. First, Kotlin is lazy on purpose: in a && b it does not even look at b if a was false, because the answer cannot change. Second, when a condition grows past about three parts, give it a name:
1val isTeen = age >= 13 && age <= 19
2if (isTeen) {
3 println("Teenager")
4}That is a val holding a Boolean, and it reads better than the thing it replaced.
The Kotlin bit: if hands back a value
In most languages if just does things. In Kotlin it is an — it produces a value, which means you can put it on the right of an =:
1val a = 12
2val b = 30
3val biggest = if (a > b) a else b
4println(biggest)No curly brackets needed for one-liners. biggest is 30.
There is one rule: an if used this way must have an else. Kotlin has to end up with a value whatever happens, and without an else there is a path that produces nothing. Leave it out and you get 'if' must have both main and 'else' branches if used as an expression.
Reading a decision line by line
- Open Pocket Studio, tap Projects, open KotlinLab, then open
Lab.kt. - Clear the inside of
mainand type in the eleven-line program from the walkthrough above. - Tap Run. You should see
Silver, thenResult: pass. - Change
val score = 72toval score = 95and run again. Now it saysGold. - Try
val score = 12. You getTry againandResult: fail. - Try exactly
val score = 60. It saysSilver, because>=includes the number itself. Change that test toscore > 60and run again — now 60 falls through toTry again. The difference between>and>=is a whole grade boundary. - Break it deliberately: delete the
elsefrom line 10 and press Run. Read the error, then put it back.
if (score) where a number sits alone in the brackets.if (score > 0). Unlike some other languages, Kotlin never treats a number as a stand-in for true or false — and that strictness stops a lot of guessing.= inside the condition. That line stores a value; it does not ask anything.if (name == "Ada"). One = puts a value in, two == compares.if on the right of an = has no else, so there is a path where nothing at all would be produced.else branch. Every route through the expression has to end up with a value.if score > 5 { rather than if (score > 5) {.if and while.{ } block and then used it outside. Names live and die with the block that declared them.if, so it is in for both branches.- runs a only when its is true; covers the other case.
- The condition must be a . Build one with
>,<,>=,<=,==or!=— and remember==compares while=assigns. else ifchains are checked in order and stop at the first match, so write the narrowest test first.- Join conditions with
&&(both),||(either) and!(not). Name long conditions. - In Kotlin
ifis an :val max = if (a > b) a else b. Used that way, theelseis compulsory. - Next: when you are testing the same value against five different possibilities, an
else ifchain gets ugly.whenis the tidy answer.