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
SlicesIndexfunction with a simpler implementation using Kotlin’s built-inindexOfmethod.We’ve implemented a
LinkedListclass to demonstrate generic classes, which is similar to theListstruct in the original Go code.The
Pushmethod is implemented aspushin Kotlin style.The
AllElementsmethod is implemented asallElementsin Kotlin style.In the
mainfunction, 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.