Advertisement
  1. Code
  2. Mobile Development
  3. Android Development

Kotlin From Scratch: Nullability, Loops, and Conditions

Scroll to top
Read Time: 10 min
This post is part of a series called Kotlin From Scratch.
Kotlin From Scratch: Variables, Basic Types, and Arrays
Kotlin From Scratch: Ranges and Collections

Kotlin is a modern programming language that compiles to Java bytecode. It is free and open source, and promises to make coding for Android even more fun.  

In the previous article, you learned about variables, simple types, arrays, comments and type inference in Kotlin. In this tutorial, we'll continue to learn the language by looking at nullability, loops, and conditions in Kotlin.

1. Nullability

If you're an Android coder, you must have come across the infamous NullPointerException errors in your app. These happen whenever you try to call a method or read a property of an object reference which is null

The good news is that Kotlin can help us avoid this kind of error because it's a null safe language. That means variables can't have the value null unless you explicitly declare their type to be nullable. In other words, by default, types cannot be null. Let's see how this feature of Kotlin can help us avoid errors in our code. 

1
val name: String = null // will not compile

As you can see above, if we assign null to the name variable, the compiler will complain. For the compiler to allow the assignment, declare name as a nullable by adding ? after the type.

1
val name: String? = null // will compile

2
name = "Chike" // new value is "Chike"

Note that if ? is inserted after any type name, we have explicitly instructed the compiler that the value of the type can either store an object reference or can be null—it is nullable. Here, we did so with the String type, but it works the same with Int?, Byte?Long?, MyClass?, and so on. 

The Safe Call Operator: ?.

Let's learn more about how null-safety works in Kotlin with an operator called the safe call operator ?..

1
var name: String? = null
2
print(name.length) // will not compile

The code above won't compile because Kotlin is a null-safe language. The variable name is assigned the value null. Now, invoking the property length on that variable would trigger a NullPointerException error in Java. But the Kotlin compiler won't allow the invocation of this property because the variable could be null. The compiler won't allow us to do something that could generate a NullPointerException!

1
val v: String? = null
2
print(v?.length) // will compile and print "null"

Now, by adding the safe call operator ?. to the variable before invoking the property, we have explicitly instructed the compiler to invoke the property only if the value isn't null. If the value is null, the compiler will use the string "null" as the value for us. This works also for methods and not just properties. 

When you call a method of a nullable, the return type will also be nullable. So, for example, the return type of the v?.length expression when v is nullable will be Int?

1
val v: String? = null
2
val len: Int? = v?.length
3
print(len) // will compile and print "null"

To bypass nullability checking by the Kotlin compiler, we can replace the ?. operator with !!.. This is not recommended, though, because of the high probability of getting NullPointerException errors if used.  

1
val v: String? = null
2
val len: Int? = v!!.length
3
print(len) // triggers a NullPointerException error

The Elvis Operator: ?:

This operator ?: is called the Elvis operator (because its shape looks like Elvis's head). It is used to provide an alternative value for the variable if it is null.  

1
val username = null
2
val name: String = username ?: "No name"
3
print(name) // will compile and print "No name"

Here, the compiler assigned the string "No name" to the variable name, because the first value username is null. If the first value was not null, then that value would be assigned to the variable instead.

2. Loops

Kotlin has while, do-while, and for loops. 

The while Loop

A repetition statement allows us to specify that code should repeat an action while some condition remains true.

So in Kotlin, using the while loop is same as in other languages such as Java.

1
while (condition) {
2
    // execute code here

3
}
4
5
while (fuel > 5) {
6
    driveMeAroundLagos()
7
}

As long as the condition is true, the code inside the curly braces or the loop's body will be executed. If the condition is false, then the code will not be executed. In our example above, once the fuel variable becomes less than 5 litres, the condition becomes false and then the loop terminates. In other words, driveMeAroundLagos() method execution stops. 

The do..while Loop

Kotlin also has the do..while loop construct. 

1
do {
2
    // execute code here

3
} while (condition)

This is similar to the while statement. In the while loop, the program tests the loop condition at the beginning of the loop before executing the loop's body. If the condition is false, the body is not executed. But the do-while loop tests the condition after executing the loop's body. This means that the body is executed at least once.

The for Loop

A for loop is a repetition statement that enables us to iterate over objects while a given condition is true.

1
for (value in range) {
2
    // Execute code

3
}   

In Kotlin, the for loop construct works with iteration over ranges, collections, or other iterables (I'll explain more about these in the next post). For loops work together with the in operator, which is used to ascertain whether a value is present in a given range.

1
for (a in 1..5) {
2
     print("$a ") // will print  1 2 3 4 5

3
}

In the code above, we are iterating through a closed range 1 to 5 and printing out each value in the range. 

Iterating Over an Index Array

We can use the withIndex() function or the indices property on an array to iterate over an array where we need the index for each element.

Using the withIndex() Function

We can iterate over an array to access each element's index by calling the withIndex() function on the array, because the withIndex() function returns an iterable of IndexedValue type for each element. This lets us access both the index and value for each element from it.

1
val numbersArray = intArrayOf(1,2,3,4,5)
2
for ((index, value) in numbersArray.withIndex()) {
3
    print("$index index value is $value\n")
4
}

The code above will print out the result below:

1
0 index value is 1
2
1 index value is 2
3
2 index value is 3
4
3 index value is 4
5
4 index value is 5

Using the indices Property

Moreover, we can use the indices property on the array. This will return just the range of valid indices for the array.

1
val numbers1 = intArrayOf(1,2,3,4,5)
2
for (index in numbers1.indices) {
3
    print("$index index value is ${numbers1[index]}\n")
4
}

The above code will produce the same result as the previous example. You can see here also that we can use the index to access an array element, similarly to other programming languages like Java.

3. Conditions

Kotlin has three types of condition statements: the if, if..else, and when statements. 

The if Statement

An if statement runs some code if a condition is true, or simply skips it if the condition is false. Nothing special here: if statements work similarly to the way they do in most other programming languages, including Java. 

1
val number = 20
2
if (number % 2 == 0) {
3
    print("$number is divisible by 2") // 20 is divisible by 2

4
}

We can also check whether a variable is of a particular type using the is keyword. 

1
if (number is Int) {
2
    print("$number is an integer")
3
}   

The if..else Statement

The if..else performs one action if the condition is true and performs a different action if the condition is false.

1
val number = 13
2
if (number % 2 == 0) {
3
    print("$number is divisible by 2")
4
} else {
5
    print("$number is not divisible by 2") // 13 is not divisible by 2

6
}

One major feature that distinguishes the if..else statement in Kotlin from other programming languages such as Java is the ability to assign a variable from the returned value of the  if..else statement. This is possible because an if..else statement can be used not just as a statement, but also as an expression in Kotlin.

1
val number = 13
2
val result = if (number % 2 == 0) {
3
    "$number is divisible by 2"
4
} else {
5
    "$number is not divisible by 2"
6
}
7
print(result) // 13 is not divisible by 2

In the code above, we assigned the result variable with a String object based on the condition of the if..else statement. Be aware that this will return only the last statement in a particular condition block and also that you can't use an if without an else as an expression. 

1
val result = if (number % 2 == 0) {
2
    "Divisible by 2"
3
    "Number is $number" // only this string is returned if executed

4
} else {
5
    "Not divisible by 2"
6
    "Number is $number"
7
}

The when Expression

Kotlin introduced the when construct as a replacement for the familiar switch statement we have in different programming languages such as C++, Java, and so on. when is more concise and has more powerful features than the switch statement you might be familiar with. 

The when statement performs different actions based on the possible values of a constant of type Int, String, Byte, Short, or any other object. 

1
fun guessTheNumber(number: Int) {
2
3
    when (number) {
4
        1 -> println("number is 1")
5
        2 -> println("number is 2")
6
        3 -> println("number is 3")
7
        else -> println("number is neither 1, 2 or 3")
8
    }
9
}

In the code above, we passed the function guessTheNumber() a number parameter (we'll discuss functions in Kotlin in a later post). The when expression then checks if any of the branches match the value of number and then executes the action on that branch. If none of the branches was a match, the else branch is executed. 

Another variant of the when expression does not require any argument, as in the example below.

1
fun guessTheNumber(number: Int) {
2
    
3
    when {
4
        number == 1 -> println("number is 1")
5
        number == 2 -> println("number is 2")
6
        number == 3 -> println("number is 3")
7
        else -> println("number is neither 1, 2 or 3")
8
    }
9
}

If we want to execute more than one action on a branch, we need to wrap the actions in curly braces {}.

1
val number = 2
2
when (number) {
3
    1 -> println("number is 1")
4
    2 -> {
5
        // block of code executed

6
        println("number is 2") 
7
        println("it is an even number")
8
    }
9
    3 -> println("number is 3")
10
}

Moreover, we can combine test values in a single branch.

1
val number = 2
2
when (number) {
3
    1, 2 -> println("number is either 1 or 2") // number is either 1 or 2

4
    3 -> println("number is 3")
5
}

Here, the first branch is executed because we are testing for a value of either 1 or 2.

Conclusion

In this tutorial, you learned about nullability, loops, and conditions in the Kotlin programming language. In the next tutorial in the Kotlin From Scratch series, you'll learn about the ranges and collections API in Kotlin. See you soon!

To learn more about the Kotlin language, I recommend visiting the Kotlin documentation. Or check out some of our other Kotlin tutorials here on Envato Tuts+!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.