๐ŸŽ“ A1Learner
๐Ÿ”
0 of 37 lessons completed

Kotlin Generic Functions

A generic function works with a type that the caller chooses. One definition holds the logic and each call picks the type that fills its type parameter.

The type follows the arguments

firstOf works for a list of numbers and a list of words. The compiler infers T from the list passed to each call.

fun <T> firstOf(items: List<T>): T {
    return items[0]
}

fun main() {
    println(firstOf(listOf(3, 5, 7)))
    println(firstOf(listOf("sun", "moon")))
}

An explicit type argument

The call writes its type in angle brackets after the function name. Both calls build a list that holds the same value twice.

fun <T> twice(value: T): List<T> {
    return listOf(value, value)
}

fun main() {
    println(twice<String>("hi"))
    println(twice<Int>(4))
}

Two type parameters with a transform

T names the input type and R names the result type. The transform lambda turns a value of type T into a value of type R.

fun <T, R> convert(value: T, transform: (T) -> R): R {
    return transform(value)
}

fun main() {
    println(convert(5) { it * 2 })
    println(convert("abc") { it.length })
}

A generic extension function

The extension adds a method to List with its own type parameter. The method reads the second item or gives null when the list is too short.

fun <T> List<T>.secondOrNull(): T? {
    return if (size >= 2) this[1] else null
}

fun main() {
    println(listOf(10, 20, 30).secondOrNull())
    println(listOf("one").secondOrNull())
}

Example

fun <T> middle(items: List<T>): T {
    return items[items.size / 2]
}

fun main() {
    println(middle(listOf(1, 2, 3, 4, 5)))
    println(middle(listOf("a", "b", "c")))
    println(middle(listOf(2.5, 1.5)))
}

Key points

  • A type parameter sits in angle brackets before the function name.
  • The compiler can infer the type parameter from the arguments of a call.
  • A call can also write its type argument in angle brackets.
  • A function can hold two type parameters and use both in its shape.
  • A generic extension function adds a generic method to an existing type.

In this example, middle reads the item at the middle position of a list. The first call passes whole numbers and prints 3. The second call passes words and prints b. The last call passes decimal numbers and prints 1.5.

Note

The body of a generic function uses the type parameter like a normal type name.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท Kotlin Playground

Exercise

A generic function is declared as fun <T> head(items: List<T>): T and called with a list of words. What does T stand for in that call?