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:
// 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 = ::PenggunaCallable 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.
// 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:
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) = 8Mari kita telaah baris-baris kode di atas:
- Baris 6 (
fun salam(nama: String): String): top-level function yang akan dirujuk. Callable reference memungkinkan kita meneruskan function ini tanpa membungkus dengan lambda. - Baris 11 (
val salamRef: (String) -> String = ::salam): reference ke functionsalam. TipesalamRefadalah(String) -> String, sama persis dengan signature functionsalam. - Baris 16 (
val doubled = angka.map(::dobelkan)): pemanggilanmapdengan callable reference::dobelkan. Lambda biasa seperti{ it * 2 }juga bisa, tetapi reference lebih ringkas bila function sudah ada. - Baris 20 (
val panjang: (String) -> Int = String::length): reference ke member function/propertyString.length. Tipe function type(String) -> Int— receiverStringmenjadi parameter pertama. - Baris 24 (
val ukuran: (List<Int>) -> Int = List<Int>::size): reference ke propertyList.size. Tipe function type menerimaList<Int>dan mengembalikanInt. - Baris 28 (
val naik: (Int) -> Int = Int::unaryMinus): reference ke member functionInt.unaryMinus(). Pemanggilan dengan argumen7menghasilkan-7. - Baris 32-33 (
val nama = "Siti"; val panjangSiti: () -> Int = nama::length): bound callable reference. Receiver sudah diikat ke instancenama, sehingga tipe function type menjadi() -> Int— tidak menerima parameter lagi. - Baris 37 (
val buatPengguna: (String, Int) -> Pengguna = ::Pengguna): reference ke constructorPengguna. MemanggilbuatPengguna("Andi", 28)sama denganPengguna("Andi", 28). Berguna untuk factory pola. - Baris 42 (
val propRef = ::dobelkan; propRef.invoke(4)): pemanggilan viainvoke()— sama seperti memanggil function biasa. Reference dapat diperlakukan sebagai nilai function type.
Jenis Callable Reference #
| Jenis | Sintaks | Contoh |
|---|---|---|
| Top-level function | ::namaFungsi | ::salam |
| Member function | Tipe::method | String::length |
| Top-level property | ::properti | ::versi |
| Member property | Tipe::properti | List::size |
| Constructor | ::NamaClass | ::Pengguna |
| Bound reference | instance::member | nama::length (receiver terikat) |
| Extension function | Tipe::extension | String::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 instancenama. 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.
// 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 #
- Higher-order functions and lambdas
— panduan callable reference
::ke function dan property - Operator overloading
— hubungan
invokeoperator dengan callable reference
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.