Callable reference adalah cara Kotlin untuk merujuk ke function, property, atau constructor yang sudah ada tanpa membungkusnya dengan lambda. Sintaksnya menggunakan tanda :: di depan nama. Pada chapter ini kita akan memahami berbagai jenis callable reference — reference ke top-level function, reference ke member function, reference ke property, bound reference yang mengikat receiver, dan reference ke constructor. Kita juga akan melihat kapan callable reference lebih cocok dipakai daripada lambda.

Apa Itu Callable Reference #

Callable reference menghasilkan nilai bertipe function type yang merujuk ke function/property/constructor yang sudah ada. Sintaksnya:

kotlin Bentuk callable reference
// Top-level function
fun salam(nama: String): String = "Halo, $nama!"
val ref: (String) -> String = ::salam

// Member function/property
val panjang: (String) -> Int = String::length

// Constructor
val buatPengguna: (String, Int) -> Pengguna = ::Pengguna

Callable reference berguna saat kita ingin meneruskan function yang sudah ada ke higher-order function — misalnya daftar.map(::dobelkan) alih-alih daftar.map { dobelkan(it) }.

Contoh Callable Reference #

Mari kita lihat semua jenis callable reference dalam satu file yang dapat dijalankan.

kotlin
// callable_references.kt
// Callable reference: rujukan ke function, property, atau constructor.

fun salam(nama: String): String = "Halo, $nama!"

fun dobelkan(n: Int): Int = n * 2

fun main() {
    // ::function — reference ke top-level function.
    val salamRef: (String) -> String = ::salam
    println(salamRef("Budi"))

    // ::function dipakai sebagai argumen.
    val angka = listOf(1, 2, 3, 4, 5)
    val doubled = angka.map(::dobelkan)
    println("Doubled: $doubled")

    // String::length — reference ke member function/property.
    val panjang: (String) -> Int = String::length
    println("Panjang \"Kotlin\": ${panjang("Kotlin")}")

    // List::size — reference property.
    val ukuran: (List<Int>) -> Int = List<Int>::size
    println("Ukuran list: ${ukuran(angka)}")

    // Int::inc — reference member function.
    val naik: (Int) -> Int = Int::unaryMinus
    println("Negasi 7: ${naik(7)}")

    // Bound callable reference (Kotlin 1.1+).
    val nama = "Siti"
    val panjangSiti: () -> Int = nama::length
    println("Panjang nama Siti: ${panjangSiti()}")

    // Reference ke constructor.
    class Pengguna(val nama: String, val umur: Int)
    val buatPengguna: (String, Int) -> Pengguna = ::Pengguna
    val p = buatPengguna("Andi", 28)
    println("Pengguna: ${p.nama}, ${p.umur} tahun")

    // Property reference untuk Top-level property.
    val propRef = ::dobelkan
    println("propRef.invoke(4) = ${propRef.invoke(4)}")
}

Output yang Dihasilkan:

text
Halo, Budi!
Doubled: [2, 4, 6, 8, 10]
Panjang "Kotlin": 6
Ukuran list: 5
Negasi 7: -7
Panjang nama Siti: 4
Pengguna: Andi, 28 tahun
propRef.invoke(4) = 8

Mari kita telaah baris-baris kode di atas:

  1. Baris 6 (fun salam(nama: String): String): top-level function yang akan dirujuk. Callable reference memungkinkan kita meneruskan function ini tanpa membungkus dengan lambda.
  2. Baris 11 (val salamRef: (String) -> String = ::salam): reference ke function salam. Tipe salamRef adalah (String) -> String, sama persis dengan signature function salam.
  3. Baris 16 (val doubled = angka.map(::dobelkan)): pemanggilan map dengan callable reference ::dobelkan. Lambda biasa seperti { it * 2 } juga bisa, tetapi reference lebih ringkas bila function sudah ada.
  4. Baris 20 (val panjang: (String) -> Int = String::length): reference ke member function/property String.length. Tipe function type (String) -> Int — receiver String menjadi parameter pertama.
  5. Baris 24 (val ukuran: (List<Int>) -> Int = List<Int>::size): reference ke property List.size. Tipe function type menerima List<Int> dan mengembalikan Int.
  6. Baris 28 (val naik: (Int) -> Int = Int::unaryMinus): reference ke member function Int.unaryMinus(). Pemanggilan dengan argumen 7 menghasilkan -7.
  7. Baris 32-33 (val nama = "Siti"; val panjangSiti: () -> Int = nama::length): bound callable reference. Receiver sudah diikat ke instance nama, sehingga tipe function type menjadi () -> Int — tidak menerima parameter lagi.
  8. Baris 37 (val buatPengguna: (String, Int) -> Pengguna = ::Pengguna): reference ke constructor Pengguna. Memanggil buatPengguna("Andi", 28) sama dengan Pengguna("Andi", 28). Berguna untuk factory pola.
  9. Baris 42 (val propRef = ::dobelkan; propRef.invoke(4)): pemanggilan via invoke() — sama seperti memanggil function biasa. Reference dapat diperlakukan sebagai nilai function type.

Jenis Callable Reference #

JenisSintaksContoh
Top-level function::namaFungsi::salam
Member functionTipe::methodString::length
Top-level property::properti::versi
Member propertyTipe::propertiList::size
Constructor::NamaClass::Pengguna
Bound referenceinstance::membernama::length (receiver terikat)
Extension functionTipe::extensionString::capitalize

Bound vs Unbound Reference #

  • Unbound: String::length — receiver belum diikat. Tipe (String) -> Int. Harus menyediakan receiver saat memanggil.
  • Bound: nama::length — receiver sudah diikat ke instance nama. Tipe () -> Int. Tidak perlu receiver lagi saat memanggil.

Kapan Memakai Callable Reference #

Callable reference lebih cocok dipakai saat function/property sudah ada dan lambda hanya membungkus satu pemanggilan. Bila transformasi memerlukan logika khusus, lambda dengan body lebih sesuai.

kotlin Perbandingan reference vs lambda
// Reference — ringkas
daftar.map(::dobelkan)

// Lambda — lebih panjang, tidak ada keuntungan
daftar.map { dobelkan(it) }

// Lambda cocok bila ada logika khusus
daftar.map { if (it > 0) it * 2 else 0 }

Referensi Lanjutan #

Penutup #

Callable reference memberi cara ringkas untuk meneruskan function yang sudah ada ke higher-order function. Dengan memahami jenis-jenis reference — top-level, member, property, constructor, dan bound — kita dapat menulis kode Kotlin yang lebih ringkas dan ekspresif. Selanjutnya, kita akan masuk ke topik function composition — cara menggabungkan beberapa function menjadi pipeline transformasi yang lebih kompleks.