Setiap lambda di Kotlin memiliki tipe yang disebut function type. Tipe ini mendeskripsikan parameter masukan dan tipe kembalian lambda, misalnya (Int, Int) -> Int atau () -> Unit. Pada chapter ini kita akan membedah berbagai bentuk function type yang dipakai di Kotlin — mulai dari yang paling dasar hingga variasi seperti nullable return type, nullable function type, suspend function type, dan receiver function type. Kita juga akan melihat bagaimana typealias dapat menyederhanakan signature function yang panjang.

Bentuk Dasar Function Type #

Function type ditulis dalam bentuk (ParameterTypes) -> ReturnType. Bila function tidak menerima parameter, ditulis () -> ReturnType. Bila function tidak mengembalikan nilai, tipe kembalian adalah Unit.

kotlin Variasi function type
val tambah: (Int, Int) -> Int = { a, b -> a + b }
val sapa: () -> Unit = { println("Halo") }
val panjang: (String) -> Int = { it.length }

Variasi Function Type Lengkap #

Kotlin mendukung banyak variasi function type untuk situasi berbeda:

TipeArtiContoh Penggunaan
(Int, Int) -> IntDua Int masuk, Int keluarOperasi aritmatika
(Int) -> Int?Bisa kembalikan nullParsing, lookup
((Int) -> Int)?Variabel function boleh nullCallback opsional
suspend (Int) -> IntSuspend lambdaCoroutine
Int.() -> IntReceiver function typeDSL, builder
() -> UnitTanpa parameter, no returnSide effect

Contoh Function Type dalam Kode #

Mari kita lihat semua variasi dalam satu file yang dapat dijalankan.

kotlin
// function_types.kt
// Variasi function type di Kotlin.

// Function type dasar: (Int, Int) -> Int
val tambah: (Int, Int) -> Int = { a, b -> a + b }

// Function type dengan return nullable: (Int) -> Int?
val parse: (String) -> Int? = { s ->
    val n = s.toIntOrNull()
    if (n != null && n >= 0) n else null
}

// Function type nullable: ((Int) -> Int)?
var pemroses: ((Int) -> Int)? = null

// Function type tanpa parameter dan tanpa return: () -> Unit
val sapa: () -> Unit = { println("Halo!") }

// Suspend function type (berjalan di coroutine).
suspend fun jalankanCoroutine(block: suspend (Int) -> Int): Int {
    return block(42)
}

// Receiver function type: Int.() -> Int (this adalah Int)
val kuadratReceiver: Int.() -> Int = { this * this }

// Function type dengan default value pada parameter.
fun cobaEksekusi(
    nilai: Int,
    transform: (Int) -> String = { "nilai=$it" }
): String {
    return transform(nilai)
}

// Function type sebagai type alias.
typealias StringToInt = (String) -> Int

val hitungPanjang: StringToInt = { it.length }

fun main() {
    println("tambah(2, 3) = ${tambah(2, 3)}")
    println("parse(\"42\") = ${parse("42")}")
    println("parse(\"abc\") = ${parse("abc")}")
    println("parse(\"-1\") = ${parse("-1")}")

    pemroses = { it + 100 }
    println("pemroses(5) = ${pemroses?.invoke(5)}")

    sapa()

    // Pemanggilan receiver function type.
    println("5.kuadratReceiver() = ${5.kuadratReceiver()}")

    // Default function type parameter.
    println(cobaEksekusi(10))
    println(cobaEksekusi(10) { "hasil=${it * 3}" })

    println("Panjang \"Budi\" = ${hitungPanjang("Budi")}")
}

Output yang Dihasilkan:

text
tambah(2, 3) = 5
parse("42") = 42
parse("abc") = null
parse("-1") = null
pemroses(5) = 105
Halo!
5.kuadratReceiver() = 25
nilai=10
hasil=30
Panjang "Budi" = 4

Mari kita telaah baris-baris kode di atas:

  1. Baris 5 (val tambah: (Int, Int) -> Int): function type paling dasar. Dua parameter Int dan tipe kembalian Int.
  2. Baris 8 (val parse: (String) -> Int?): function type dengan nullable return type. Tanda ? setelah Int menandakan lambda boleh mengembalikan null. Body parse mengembalikan n (bila valid) atau null.
  3. Baris 14 (var pemroses: ((Int) -> Int)? = null): function type nullable — ? di luar kurung. Variabel pemroses boleh menampung lambda atau null. Saat memanggil, kita pakai ?.invoke() untuk aman.
  4. Baris 18 (val sapa: () -> Unit): function type tanpa parameter dan tanpa nilai kembalian. Sering dipakai untuk callback side-effect.
  5. Baris 21 (suspend fun jalankanCoroutine(block: suspend (Int) -> Int)): function suspend yang menerima lambda suspend. Kata kunci suspend menandakan lambda boleh memanggil function suspend lain — bagian dari coroutine.
  6. Baris 26 (val kuadratReceiver: Int.() -> Int): receiver function type. Bentuk A.() -> B berarti lambda menerima A sebagai this di dalam body. Kita akan mendalami ini pada chapter khusus.
  7. Baris 29 (fun cobaEksekusi(nilai: Int, transform: (Int) -> String = { "nilai=$it" })): function type sebagai parameter dengan default value. Bila pemanggil tidak menyediakan lambda, default dipakai.
  8. Baris 37 (typealias StringToInt = (String) -> Int): type alias menyederhanakan signature panjang. Setelah alias, StringToInt dapat dipakai sebagai pengganti (String) -> Int.

Suspend Function Type #

Suspend function type seperti suspend (Int) -> Int dipakai dalam coroutine. Lambda bertipe ini dapat memanggil function suspend lain seperti delay() atau melakukan operasi I/O non-blocking. Suspend function type tidak dapat dipanggil langsung dari kode non-suspend — harus dipanggil dari dalam coroutine scope.

Receiver Function Type — Pengantar #

Bentuk Receiver.() -> ReturnType adalah receiver function type. Di dalam body lambda, this otomatis merujuk ke receiver — seolah-olah lambda adalah extension function. Kita akan membedah konsep ini pada chapter Receiver Function Types dan Extension Lambdas.

typealias untuk Function Type #

Ketika signature function type panjang atau dipakai berulang, typealias membantu membuat kode lebih mudah dibaca. Contoh:

kotlin typealias untuk function type
typealias Mapper<T, R> = (T) -> R
typealias Validator<T> = (T) -> Boolean

val toUpper: Mapper<String, String> = { it.uppercase() }
val isPositive: Validator<Int> = { it > 0 }

Typealias tidak membuat tipe baru — hanya alias. Kompilator tetap memperlakukan Mapper<String, String> sebagai (String) -> String.

Referensi Lanjutan #

Penutup #

Function type adalah bahasa formal untuk mendeskripsikan lambda di Kotlin. Dengan menguasai variasi — dari dasar (Int) -> Int hingga nullable, suspend, dan receiver function type — kita dapat membaca signature library apapun dan menulis API yang ekspresif. Selanjutnya, kita akan mendalami receiver function type yang menjadi dasar pembangunan DSL Kotlin.