Kotlin If, When and While - mariamaged/Java-Android-Kotlin GitHub Wiki
Kotlin - If, When and While
- if is nearly ubiquitous in computer programming.
Java
if(i > 10) {
// Do something.
}
else {
// Do something else.
}
JavaScript
if(i > 10) {
// Do something.
}
else {
// Do something else.
}
// Yes, it is the same as Java syntax.
Ruby
if(i > 10)
# Do something.
else
# Do something.
end
Kotlin
val i = 3
if(i > 10) {
println("Something")
}
else {
println("Something else")
}
For single-line conditional work, you can skip the braces.
val i = 3
if(i > 10) println("Something") else println("Something else")
- It also supports
else ifin addition to a simple else:
val i = 3
if(i > 10) println("Something")
else if(i > 2) println("Something else")
else println("And now for something completely different")
When
when is distinctive.
when is powerful.
when is used a lot in Kotlin programming.
What We Do Elsewhere
- The closest analogy to
whenin Java is theswitchstatement. - Here, depending on the value of
foo, we evaluate one set of statement that follows the matchingcase(or thedefaultstatements, if there are no matches).
switch(foo) {
case 1:
// Do something.
break;
case 2:
// Do something else.
break;
default:
// Like, whatever.
}
- Javascript also has a switch, with same syntax as Java.
- Ruby uses
case, and it is the closest of the three in terms of matching the power ofwhen.
case foo
when 1
# Do something.
when 2
# Do something else.
else
# Like, whatever.
end
The Basic Use of when
The most commonly-seen of when looks like a Java/ JavaScript switch or Ruby case, when you supply a value for comparison and set up different branch conditions to test against that value:
val i = 3
when(i) {
1 -> println("Something")
2 -> println("Something else")
else -> println("And now for something completely different")
}
- Each branch has a
value. - That is compared to an
input.
- The
first matchhas its statement or blockevaluated, and everything else isskipped.- If there are no matches, the
elsestatement or block is evaluated.
- If there are no matches, the
- The -> separates the branch comparison to the stuff that should be executed if that branch comparison is met.
In this case, the output is:
And now for something completely different.
- Anything that can be compared using equality (==) can be used.
val things = "foo"
when (thingy) {
"foo" -> println("Something")
"bar" -> println("Something else")
else -> println("And now for something completely different")
}
- However, you cannot mix types, unless *== happens to work to compare them.
- This, for example, fails with a compiler error, pointing out that
IntandStringareincompatible types:
val things = "foo"
when(things) {
"foo" -> println("Something.")
2 -> println("Something else.")
else -> println("And now for something completely different")
}
Using when instead of else if
The when syntax from the preceding section is fairly similar to switch and case. However,
whenhas many more options.
- One option is to skip the parameter to the when.
- In that case, each branch has its own
Boolean expression, and thefirstthat evaluates to true is used. - This results in a more direct analogue to
if else/ if else.
val i = 3
when {
i > 10 -> println("Something")
i > 2 -> println("Something else")
else -> println("And now for something completely different")
}
Consolidating Multiple Branches
- If you have a
few valuesthat all should route to the same branch, you can use acomma-delimited listinstead of asingle valuefor the branch comparison.- Kotlin will compare each of the comma-delimited values and if
any of them match, that branch is used.
- Kotlin will compare each of the comma-delimited values and if
- For numbers, you can use
..syntax andinto set up a "range" and test against it.
val thingy = "foo"
when(thingy) {
"foo", "goo" -> println("Something")
"bar", "baz", "frobozz" -> println("Something else")
else -> println("And now for something completely different")
}
val i = 3
when(i) {
in 3..10 -> println("Something")
in 1..2 -> println("Something else")
else -> println("And now for something completely different")
}
Expressions As Branch Conditions
- The value for comparison does not need to be constant - any expression will work.
- Here, the second branch compares
thingytootherThingy.toLowerCase()- in this case, they are equal, and so that branch is used.
val thingy = "bar"
val otherThingy = "BAR"
when(thingy) {
"foo", "goo" -> println("Something")
otherThingy.toLowerCase() -> println("Something else")
else -> println("And now for something completely different")
}
While
Just as
ifis fairly common in programming languages, so iswhileor some other loop that is based on evaluating a condition.
Java
int i = 0
while(i < 10) {
i++;
}
JavaScript
var i = 0;
while(i < 10) {
i++;
}
Ruby
i = 0
while i < 10
i += 1
end
Kotlin
var i = 0
while(i < 10) {
i++
println(i)
}
- However,
whileis not common in Kotlin as it is in other languages. - More often we use operations on collection (e.g,
forEach()) rather than while. - However, it exists, should you find the need for it.
when Expressions
- when can also be used as an expression:
val i = 3
val message = when(i) {
in 3..10 -> "Something"
in 1..2 -> "Something else"
else -> "And now for something completely different"
}
println(message) // Prints "Something".
- Technically, the branches of the if or when do not have to evaluate to the same type.
val i = 3
val message = when(i) {
in 3..10 -> "Soemthing"
in 1..2 -> 5
else -> "And now for something completely different"
}
println(message) // Prints "Something"
- However, you will get some compiler warnings:
- Here, the compiler is telling you that since the branches evaluated to different types, the implied type of
messageisAny. Anyin Kotlin is roughly analogous toObjectin Java - it is the root type of the class hierarchy.- Every class in Kotlin eventually extends from Any.
- Any is the common ancestor class of Int and String, which is why the compiler chose that as the type for message.
- The warning is there to hint to you that perhaps what you wrote is not what you really have in mind.
Else Required
- Normally, if and when do not have to be
exhaustive.- Exhaustive means that all possibilities are covered by some branch.
Examples for exhaustive:
if(i > 10) {
// Do something.
}
else {
// Do something else.
}
Examples for not exhaustive:
if(i > 10) {
// Do something.
}
val i = 3
when {
i > 10 -> println("Something")
i > 2 -> println("Something else")
}
- In these cases, there are values for i for which none of the branches is valid.
- For
standaloneif and when statements, this is fine. - However, if you are going to use if and when as
expressions, they must be exhaustive.
- If you try a non-exhaustive if or when for an expression, such as:
val i = 3
val message = when(i) {
in 3..10 -> "Something"
in 1..2 -> 5
}
println(message)
... you will get a compilation error.
Bustin' Out
Sometimes, while you in a loop, you will want to change the normal flow of the loop.
For example, you are in a for loop, and after the 5th item, you wish to exit the loop, perhaps in response to some signal (e.g., a cancellation flag was set).
- You can always return to exit the entire function that you are in.
- Beyond that, though, there are two loop control statements that you can use:
- break.
- continue.
- These work much like their counterparts in Java and other programming languages.
break
- Abandon the loop.
var i = 0
while(i < 10) {
i++
if(i == 5) break
println(i)
}
- Once i is equal to 5, we break out of the loop.
- Since we are doing that before the
println()call, we do not print 5 to the output.
1
2
3
4
continue
- Skip the rest of this pass through the loop, and move along to the next pass through the loop.
var i = 0
while(i < 10) {
i++
if(i == 5) continue
println(i)
}
- We are going through the loop all 10 times, unlike in the break clause.
- However, we are skipping part of the loop via
continue-specifically we are skipping over the println() call.
1
2
3
4
6
7
8
9
10