Generics in Kotlin
Kotlin has supported generics since its inception, which allows for writing flexible and reusable code that can work with different types.
import kotlin.collections.List
// As an example of a generic function, `slicesIndex` takes
// a list of any type T and an element of that type and returns
// the index of the first occurrence of v in s, or -1 if not present.
fun <T> slicesIndex(s: List<T>, v: T): Int {
return s.indexOf(v)
}
// As an example of a generic class, `List` is a
// singly-linked list with values of any type.
class LinkedList<T> {
private data class Node<T>(var value: T, var next: Node<T>? = null)
private var head: Node<T>? = null
private var tail: Node<T>? = null
// We can define methods on generic types just like we
// do on regular types.
fun push(v: T) {
val newNode = Node(v)
if (tail == null) {
head = newNode
tail = newNode
} else {
tail?.next = newNode
tail = newNode
}
}
// allElements returns all the List elements as a list.
fun allElements(): List<T> {
val elements = mutableListOf<T>()
var current = head
while (current != null) {
elements.add(current.value)
current = current.next
}
return elements
}
}
fun main() {
val s = listOf("foo", "bar", "zoo")
// When invoking generic functions, we can often rely
// on type inference. Note that we don't have to
// specify the type for T when calling `slicesIndex` -
// the compiler infers it automatically.
println("index of zoo: ${slicesIndex(s, "zoo")}")
// ... though we could also specify it explicitly.
val _ = slicesIndex<String>(s, "zoo")
val lst = LinkedList<Int>()
lst.push(10)
lst.push(13)
lst.push(23)
println("list: ${lst.allElements()}")
}
When you run this program, you should see:
index of zoo: 2
list: [10, 13, 23]
In this Kotlin version:
We’ve replaced the
SlicesIndex
function with a simpler implementation using Kotlin’s built-inindexOf
method.We’ve implemented a
LinkedList
class to demonstrate generic classes, which is similar to theList
struct in the original Go code.The
Push
method is implemented aspush
in Kotlin style.The
AllElements
method is implemented asallElements
in Kotlin style.In the
main
function, we demonstrate the use of these generic constructs.
Kotlin’s type inference is generally more powerful than Go’s, so we don’t need to explicitly specify type parameters as often. However, we can still do so when needed, as shown in the example.
Kotlin’s generics system is similar to Java’s, with some additional features. It supports declaration-site variance and use-site variance, which provide more flexibility in how generic types can be used.