Norway


This article explores the of ’s Nothing type in . We look at its relationship to Java. To take a concrete example, let’s look at a linked list.

Fig. 1: A LinkedList  - a linked list - Kotlin’s Nothing: Its Usefulness in Generics

A LinkedList wraps some type T. The linked list can either be

  • A Node<T> with two properties: a payload of T and a next of type LinkedList<T>; or
  • An EmptyList.
  • A sealed class enforces that the LinkedList is either type 1 or type 2.

We can readily code up the sealed class and the Node<T> as follows:

sealed class LinkedList<out T>  {

     class Node<T>(val payload: T, var next: LinkedList<T> ) : LinkedList<T>()
}

Coding up the empty list is a bit more challenging. All empty lists are the same. So, an empty list is an object. EmptyList must also be a subclass of LinkedList<T>. We might try to write

sealed class LinkedList<out T>  {

    data class Node<T>(val payload: T, var next: LinkedList<T> ) : LinkedList<T>()

    object EmptyList<T> : LinkedList<T>() // won't compile

}

Kotlin objects cannot have type parameters. The above code will not compile. Instead, we might try to remove the EmptyList’s type parameter.

sealed class LinkedList<out T>  {

    data class Node<T>(val payload: T, var next: LinkedList<T> ) : LinkedList<T>()

    object EmptyList : LinkedList<T>() // won't compile

}

The code still does not compile. The reference to T in line 5 is unresolved. We must stipulate a concrete type for T.

T is the type of the payload wrapped by a node. See Fig. 1 above. By contrast, an empty list wraps no payload. So, the proper coding is

sealed class LinkedList<out T>  {

    data class Node<T>(val payload: T, var next: LinkedList<T> = EmptyList) : LinkedList<T>()

    object EmptyList : LinkedList<Nothing>()

}

val nonEmptyList = LinkedList.Node(payload = "A", next = LinkedList.Node(payload = "B"))

What is the Kotlin Nothing type? From Studio, select Tools -> Kotlin -> Kotlin REPL. In the REPL window, enter and run the command println(Nothing::class.java). The result is

println(Nothing::class.java)
class java.lang.Void

Kotlin’s Nothing type is backed by Java’s Void type. Kotlin’s Nothing type indicates the absence of type.

As a side point, why can’t we define a Kotlin function to return Nothing? For example, this code will not compile:

fun getNothing() = Nothing() // won't compile

Kotlin does not allow Nothing to be instantiated. The constructor for Nothing is private. Compare the above code to the Java equivalent:

public class GetVoidExample {

    public Void getVoid() {
        return new Void(); // won't compile
    }
}

Java’s Void class has a private constructor. Void cannot be instantiated. We cannot return a Void. So, it seems reasonable that we cannot return a Nothing in Kotlin.

We have shown that Kotlin’s Nothing type is backed by Java’s Void type. Kotlin’s Nothing type is used to indicate that a generic type wraps no type. The type is absent.

Allan Caine is a Big Nerd Ranch Alumni. If you would like to connect with Allan, visit his LinkedIn at https://www.linkedin.com/in/adcaine/.



Source link

LEAVE A REPLY

Please enter your comment!
Please enter your name here