Kotlin Control Flow

Regardless of the programming language used, application development is largely an exercise in applying logic, and much of the art of programming involves writing code that makes decisions based on one or more criteria. Such decisions define which code gets executed, how many times it is executed, and, conversely, which code gets bypassed when the program is running. This is often referred to as control flow since it controls the flow of program execution. Control flow typically falls into the categories of looping control (how often code is executed) and conditional control flow (whether or not code is executed). This chapter is intended to provide an introductory overview of both types of control flow in Kotlin.

Looping control flow

This chapter will begin by looking at control flow in the form of loops. Loops are essentially sequences of Kotlin statements that are to be executed repeatedly until a specified condition is met. The first looping statement we will explore is the for loop.

The Kotlin for-in Statement

The for-in loop is used to iterate over a sequence of items contained in a collection or number range. The syntax of the for-in loop is as follows:

for variable name in collection or range {
         // code to be executed
}Code language: plaintext (plaintext)

In this syntax, variable name is the name to be used for a variable that will contain the current item from the collection or range through which the loop is iterating. The code in the body of the loop will typically use this name as a reference to the current item in the loop cycle. The collection or range references the item through which the loop is iterating. This could, for example, be an array of string values, a range operator, or even a string of characters.

Consider, for example, the following for-in loop construct:

 

You are reading a sample chapter from Jetpack Compose 1.6 Essentials.

Buy the full book now in Print or eBook format. Learn more.

Preview  Buy eBook  Buy Print

 

for (index in 1..5) {
  println("Value of index is $index")
}Code language: Kotlin (kotlin)

The loop begins by stating that the current item is to be assigned to a variable named index. The statement then declares a closed range operator to indicate that the for loop is to iterate through a range of numbers, starting at 1 and ending at 5. The body of the loop simply prints out a message to the console indicating the current value assigned to the index constant, resulting in the following output:

Value of index is 1
Value of index is 2
Value of index is 3
Value of index is 4
Value of index is 5Code language: plaintext (plaintext)

The for-in loop is of particular benefit when working with collections such as arrays. In fact, the for-in loop can be used to iterate through any object that contains more than one item. The following loop, for example, outputs each of the characters in the specified string:

for (index in "Hello") {
  println("Value of index is $index")
}Code language: Kotlin (kotlin)

The operation of a for-in loop may be configured using the downTo and until functions. The downTo function causes the for loop to work backward through the specified collection until the specified number is reached. The following for loop counts backward from 100 until the number 90 is reached:

for (index in 100 downTo 90) {
  print("$index.. ")
}Code language: Kotlin (kotlin)

When executed, the above loop will generate the following output:

100.. 99.. 98.. 97.. 96.. 95.. 94.. 93.. 92.. 91.. 90..Code language: plaintext (plaintext)

The until function operates in much the same way with the exception that counting starts from the bottom of the collection range and works up until (but not including) the specified endpoint (a concept referred to as a half-closed range):

 

You are reading a sample chapter from Jetpack Compose 1.6 Essentials.

Buy the full book now in Print or eBook format. Learn more.

Preview  Buy eBook  Buy Print

 

for (index in 100 downTo 90) {
  print("$index.. ")
}Code language: Kotlin (kotlin)

The output from the above code will range from the start value of 1 through to 9:

1.. 2.. 3.. 4.. 5.. 6.. 7.. 8.. 9..Code language: plaintext (plaintext)

The increment used on each iteration through the loop may also be defined using the step function as follows:

for (index in 0 until 100 step 10) {
  print("$index.. ")
}Code language: Kotlin (kotlin)

The above code will result in the following console output:

0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90..

The while loop

The Kotlin for loop described previously works well when it is known in advance how many times a particular task needs to be repeated in a program. There will, however, be instances where code needs to be repeated until a certain condition is met, with no way of knowing in advance how many repetitions are going to be needed to meet that criterion. To address this need, Kotlin includes the while loop.

Essentially, the while loop repeats a set of tasks while a specified condition is met. The while loop syntax is defined as follows:

 

You are reading a sample chapter from Jetpack Compose 1.6 Essentials.

Buy the full book now in Print or eBook format. Learn more.

Preview  Buy eBook  Buy Print

 

while condition {
      // Kotlin statements go here
}Code language: plaintext (plaintext)

In the above syntax, condition is an expression that will return either true or false and the // Kotlin statements go here comment represents the code to be executed while the condition expression is true. For example:

var myCount = 0
 
while  (myCount < 100) {
    myCount++
    println(myCount)
}Code language: Kotlin (kotlin)

In the above example, the while expression will evaluate whether the myCount variable is less than 100. If it is already greater than 100, the code in the braces is skipped and the loop exits without performing any tasks.

If, on the other hand, myCount is not greater than 100 the code in the braces is executed and the loop returns to the while statement and repeats the evaluation of myCount. This process repeats until the value of myCount is greater than 100, at which point the loop exits.

The do … while loop

It is often helpful to think of the do … while loop as an inverted while loop. The while loop evaluates an expression before executing the code contained in the body of the loop. If the expression evaluates to false on the first check then the code is not executed. The do … while loop, on the other hand, is provided for situations where you know that the code contained in the body of the loop will always need to be executed at least once. For example, you may want to keep stepping through the items in an array until a specific item is found. You know that you have to at least check the first item in the array to have any hope of finding the entry you need. The syntax for the do … while loop is as follows:

do {
       // Kotlin statements here
} while conditional expressionCode language: plaintext (plaintext)

In the do … while example below the loop will continue until the value of a variable named i equals 0:

 

You are reading a sample chapter from Jetpack Compose 1.6 Essentials.

Buy the full book now in Print or eBook format. Learn more.

Preview  Buy eBook  Buy Print

 

var i = 10
 
do {
   i--
   println(i)
} while (i > 0)Code language: Kotlin (kotlin)

Breaking from Loops

Having created a loop, it is possible that under certain conditions you might want to break out of the loop before the completion criteria have been met (particularly if you have created an infinite loop). One such example might involve continually checking for activity on a network socket. Once activity has been detected it will most likely be necessary to break out of the monitoring loop and perform some other task.

To break out of a loop, Kotlin provides the break statement which breaks out of the current loop and resumes execution at the code directly after the loop. For example:

var j = 10
 
for (i in 0..100)
{
    j += j
 
    if (j > 100) {
        break
    }
 
    println("j = $j")
}Code language: Kotlin (kotlin)

In the above example, the loop will continue to execute until the value of j exceeds 100 at which point the loop will exit and execution will continue with the next line of code after the loop.

The continue statement

The continue statement causes all remaining code statements in a loop to be skipped, and execution to be returned to the top of the loop. In the following example, the println function is only called when the value of variable i is an even number:

var i = 1
 
while (i < 20)
{
        i += 1
 
        if (i % 2 != 0) {
            continue
        }
 
        println("i = $i")
}Code language: Kotlin (kotlin)

The continue statement in the above example will cause the println call to be skipped unless the value of i can be divided by 2 with no remainder. If the continue statement is triggered, execution will skip to the top of the while loop and the statements in the body of the loop will be repeated (until the value of i exceeds 19).

 

You are reading a sample chapter from Jetpack Compose 1.6 Essentials.

Buy the full book now in Print or eBook format. Learn more.

Preview  Buy eBook  Buy Print

 

Break and continue labels

Kotlin expressions may be assigned a label by preceding the expression with a label name followed by the @ sign. This label may then be referenced when using break and continue statements to designate where execution is to resume. This is particularly useful when breaking out of nested loops. The following code contains a for loop nested within another for loop. The inner loop contains a break statement which is executed when the value of j reaches 10:

for (i in 1..100) {
    
    println("Outer loop i = $i")
    
    for (j in 1..100) {        
        println("Inner loop j = $j")       
        if (j == 10) break
    }
}Code language: Kotlin (kotlin)

As currently implemented, the break statement will exit the inner for loop but execution will resume at the top of the outer for loop. Suppose, however, that the break statement is required to also exit the outer loop. This can be achieved by assigning a label to the outer loop and referencing that label with the break statement as follows:

outerloop@ for (i in 1..100) {
    
    println("Outer loop i = $i")
    
    for (j in 1..100) {
        
        println("Inner loop j = $j")
        
        if (j == 10) break@outerloop
    }
}Code language: Kotlin (kotlin)

Now when the value assigned to variable j reaches 10 the break statement will break out of both loops and resume execution at the line of code immediately following the outer loop.

Conditional control flow

In the previous chapter, we looked at how to use logical expressions in Kotlin to determine whether something is true or false. Since programming is largely an exercise in applying logic, much of the art of programming involves writing code that makes decisions based on one or more criteria. Such decisions define which code gets executed and, conversely, which code gets bypassed when the program is executing.

Using the if expressions

The if expression is perhaps the most basic of control flow options available to the Kotlin programmer. Programmers who are familiar with C, Swift, C++, or Java will immediately be comfortable using Kotlin if statements, although there are some subtle differences.

 

You are reading a sample chapter from Jetpack Compose 1.6 Essentials.

Buy the full book now in Print or eBook format. Learn more.

Preview  Buy eBook  Buy Print

 

The basic syntax of the Kotlin if expression is as follows:

if (boolean expression) { 
    // Kotlin code to be performed when expression evaluates to true 
}Code language: Kotlin (kotlin)

Unlike some other programming languages, it is important to note that the braces are optional in Kotlin if only one line of code is associated with the if expression. In fact, in this scenario, the statement is often placed on the same line as the if expression.

Essentially if the Boolean expression evaluates to true then the code in the body of the statement is executed. If, on the other hand, the expression evaluates to false the code in the body of the statement is skipped.

For example, if a decision needs to be made depending on whether one value is greater than another, we would write code similar to the following:

val x = 10    
 
if (x > 9) println("x is greater than 9!")Code language: Kotlin (kotlin)

Clearly, x is indeed greater than 9 causing the message to appear in the console panel.

 

You are reading a sample chapter from Jetpack Compose 1.6 Essentials.

Buy the full book now in Print or eBook format. Learn more.

Preview  Buy eBook  Buy Print

 

At this point, it is important to notice that we have been referring to the if expression instead of the if statement. The reason for this is that unlike the if statement in other programming languages, the Kotlin if returns a result. This allows if constructs to be used within expressions. As an example, a typical if expression to identify the largest of two numbers and assign the result to a variable might read as follows:

if (x > y)
    largest = x
else
    largest = yCode language: Kotlin (kotlin)

The same result can be achieved using the if statement within an expression using the following syntax:

variable = if (condition) return_val_1 else return_val_2Code language: Kotlin (kotlin)

The original example can, therefore be re-written as follows:

val largest = if (x > y) x else yCode language: Kotlin (kotlin)

The technique is not limited to returning the values contained within the condition. The following example is also a valid use of if in an expression, in this case assigning a string value to the variable:

val largest = if (x > y) "x is greatest" else "y is greatest"
println(largest)Code language: Kotlin (kotlin)

For those familiar with programming languages such as Java, this feature allows code constructs similar to ternary statements to be implemented in Kotlin.

 

You are reading a sample chapter from Jetpack Compose 1.6 Essentials.

Buy the full book now in Print or eBook format. Learn more.

Preview  Buy eBook  Buy Print

 

Using if … else … expressions

The next variation of the if expression allows us to also specify some code to perform if the expression in the if expression evaluates to false. The syntax for this construct is as follows:

if (boolean expression) { 
    // Code to be executed if expression is true 
} else { 
    // Code to be executed if expression is false 
}Code language: Kotlin (kotlin)

The braces are, once again, optional if only one line of code is to be executed.

Using the above syntax, we can now extend our previous example to display a different message if the comparison expression evaluates to be false:

val x = 10    
    
if (x > 9) println("x is greater than 9!") 
    else println("x is less than 9!")Code language: Kotlin (kotlin)

In this case, the second println statement will execute if the value of x was less than 9.

Using if … else if … Expressions

So far we have looked at if statements that make decisions based on the result of a single logical expression. Sometimes it becomes necessary to make decisions based on several different criteria. For this purpose, we can use the if … else if … construct, an example of which is as follows:

 

You are reading a sample chapter from Jetpack Compose 1.6 Essentials.

Buy the full book now in Print or eBook format. Learn more.

Preview  Buy eBook  Buy Print

 

var x = 9
 
if (x == 10) println("x is 10")
        else if (x == 9) println("x is 9")
            else if (x == 8) println("x is 8")
                 else println("x is less than 8")
}Code language: Kotlin (kotlin)

Using the when statement

The Kotlin when statement provides a cleaner alternative to the if … else if … construct and uses the following syntax:

when (value) {
       match1 -> // code to be executed on match
       match2 -> // code to be executed on match
       .
       .
       else -> // default code to executed if no match
}Code language: Kotlin (kotlin)

Using this syntax, the previous if … else if … construct can be rewritten to use the when statement:

when (x) {
    10 -> println ("x is 10")
    9 -> println("x is 9")
    8 -> println("x is 8")
    else ->  println("x is less than 8") 
}Code language: Kotlin (kotlin)

The when statement is similar to the switch statement found in many other programming languages.

Summary

The term control flow is used to describe the logic that dictates the execution path that is taken through the source code of an application as it runs. This chapter has looked at the two types of control flow provided by Kotlin (looping and conditional) and explored the various Kotlin constructs that are available to implement both forms of control flow logic.


Categories