Nullable Types

In the previous tutorial, we created a simple "Hello world" application. To enhance this it would be useful to query the user for their name to greet them personally. In Kotlin, getting user input is easier than Java, as we can use the readLine() function. One might infer from this that we could amend our previous application as follows:

fun main(args: Array<String>){

    println("Please type your name")
    val name = readLine()

    val greeting = greet(name)
    println(greeting)
}

fun greet(name: String) : String {
    
    return "hello $name"
}
If you were to try and run this code however, it would not compile, and you would see an error the first time you try and use the name variable.

Null values in Kotlin

In Java, it is perfectly acceptable to write code such as

String myString = null; // Valid Java
In Kotlin however, we are not permitted to explicitly declare a String as null, thus the following code would be invalid
var myString: String = null //Invalid Kotlin

Kotlin has been designed to avoid a whole class of errors that plague languages like Java, that of unexpected null references. (Chances are by now you will have encountered a NullPointerException when writing Java code). To do this, it prohibits values of objects, (such as String) from being null. Most of the time this will suit us just fine, however on the occasions where there is a valid reason why a value should be null, we need to know how to deal with it.

In the above example, readLine() can be used to read from either the console or a file on disk, so, when reading from disk, it needs to differentiate between what it returns when it encounters a line of text that had no content (i.e. an empty String), from what it returns when it reaches the end of a file (nothing or null). The name variable therefore represents a nullable String. We could explicitly declare it's type as follows:

val name : String? = readLine()

This still doesn't solve our problem above, as we need a regular String to pass into our greet) method. Fortunately, Kotlin provides a couple of ways to do this:

Task

Modify the initial, non-compiling code so that it works, firstly by using the check for null state and smart cast, then secondly using the non-null assertion operator

Task 2

Modify the code, so that the greet() method's name parameter is an optional String, and return a (regular) String with "hello" followed by either the person's name, or "world" if the parameter is null.

Task 3

Read through the Kotlin Documentation on null safety, and then modify your code for task 2 above, so that it uses the Elvis operator