Implementing a linked list in Kotlin
I recently started learning Kotlin, so I decided to implement some data structures in it. So, I tried implementing a singly linked list:
package datastructures
public class LinkedList {
private data class Node(var nodeValue: Int, var next: Node? = null)
private var head: Node? = null
fun insert(n: Int) {
if(head == null) head = Node(n)
else {
var cur = head
while(cur?.next != null) {
cur = cur?.next
}
cur?.next = Node(n)
}
}
fun print() {
var cur = head
while(cur != null) {
print("${cur.nodeValue} ")
cur = cur?.next
}
}
}
fun main(args: Array<String>) {
val n = LinkedList()
n.insert(5)
n.insert(3)
n.print()
}
and I got the following error:
Error:(22, 13) Kotlin: [Internal Error] org.jetbrains.jet.codegen.CompilationException: Back-end (JVM) Internal error: cannot store to value org.jetbrains.jet.codegen.StackValue$OnStack@a0a447f
Cause: cannot store to value org.jetbrains.jet.codegen.StackValue$OnStack@a0a447f
File being compiled and position: (22,13) in C:/Users/Khaled/IdeaProjects/Kotlin/src/LinkedList.kt
PsiElement: cur?.next = Node(n)
The root cause was thrown at: StackValue.java:75
at org.jetbrains.jet.codegen.ExpressionCodegen.genQualified(ExpressionCodegen.java:243)
at org.jetbrains.jet.codegen.ExpressionCodegen.genStatement(ExpressionCodegen.java:262)
at ...
I've searched here and on google but can't figure out what is the problem causing this error.
Edit:
So I tried to re-implement the function insert
and use requireNotNull()
to avoid the compiler about null safety.
Here is the code and now it works:
fun insert(n: Int) {
if (head == null) head = Node(n)
else {
var cur = head!!
while (cur.next != null) {
cur = cur.next!!
}
cur.next = Node(n)
}
}
source to share
I think the problem lies in this line:
cur?.next = Node(n)
The problem is, the compiler doesn't know what to do if cur
- null
. This currently results in an internal error, but this may be supported in a future release.
Currently, the best solution is to rewrite the code in such a way that the compiler can check that cur
never null
. The problem is that the compiler assumes that fields declared as var
can change at any time, so their values โโmust be loaded into local variables before checking for null
:
var cur = head
if(cur == null) head = Node(n)
else {
var next = cur.next
while(next != null) {
cur = next
next = cur.next
}
cur.next = Node(n)
}
source to share