Optionals

An optional type is a type whose variables may or may not contain a value. Kotlin offers extensive support for optional types.

An example of a situation where optional types come into play is the readLine() function, which reads a line of text from the console. An obscure technical issue with this function is that the user can cancel a read from the console by pressing the control-d key combination, which generates an end-of-file character. In this case, the readLine() funtion will return the special value of null, which indicates the absence of a value.

An optional, or nullable type, is indicated by placing a ? after the base type.

print("Enter your name:")
val name : String? = readLine()

The type of name in this example is a nullable String. If the user cancels the read by pressing control-d, name will contain the special value of null; otherwise, it will contain a String.

The presence of a possible null value complicates actions such as calling a member function or accessing a property. In Java if you try to call a method on a null you will get a null pointer exception. Kotlin is designed to largely eliminate the possibility of null pointer exceptions through the use of a special set of language features. The most basic of these is the safe call operator ?.

println("Your name has $(name?.length) letters in it.")

The safe call operator is designed to return null when applied to a null. If the value is not null the safe call operator will go ahead and access the property or method normally.

An alternative to the safe call operator is the Elvis operator ?:, which allows you specify a default value to use in case the value of the variable you apply it to is null:

println("Your name has $(name?.length ?: 0) letters in it.")

Force unwrapping

If you are certain that an optional does not contain a null value you can coerce the optional type to a non-optional type through the use of the force unwrapping operator !!:

val name = readLine() // Type of name is String?
if (name != null) {
  print("Your name has \(name!!.length) letters in it.")
} else {
  print("You did not enter a name.")
}