Beberapa operasi terasa lebih natural bila ditulis sebagai a op b daripada a.op(b). Pemanggilan 2 kali 3 lebih mudah dibaca daripada 2.kali(3) pada konteks matematika. Kotlin menyediakan infix functions untuk kebutuhan ini. Pada chapter ini kita akan melihat cara mendeklarasikan infix function dan aturan pemanggilannya.
Deklarasi infix Function #
Keyword infix diletakkan sebelum fun. Infix function harus menjadi member function atau extension function, dan harus menerima tepat satu parameter. Pemanggilan dilakukan dengan bentuk penerima namaFunction argumen.
infix fun Int.kali(x: Int): Int = this * x
infix fun String.berulang(n: Int): String = this.repeat(n)
infix fun String.sambung(other: String): String = "$this-$other"
fun main() {
val hasil = 2 kali 3
println("2 kali 3 = $hasil")
val garis = "-" berulang 10
println("Garis: $garis")
val namaGabung = "kotlin" sambung "dasar"
println("Nama gabung: $namaGabung")
val berurutan = (5 kali 4) kali 2
println("5 kali 4 kali 2 = $berurutan")
}Output yang Dihasilkan:
2 kali 3 = 6
Garis: ----------
Nama gabung: kotlin-dasar
5 kali 4 kali 2 = 40Mari kita bedah baris per baris:
infix fun Int.kali(x: Int): Int = this * x: extension function padaIntdengan satu parameterx. Kata kunciinfixmengizinkan pemanggilan dengan bentuk2 kali 3.infix fun String.berulang(n: Int): extension function padaStringdengan parameterInt. Pemanggilan"-", 10ditulis"-" berulang 10.2 kali 3: bentuk infix setara dengan2.kali(3). Kompilator menerjemahkan keduanya ke pemanggilan yang sama.(5 kali 4) kali 2: pemanggilan infix berantai wajib diberi tanda kurung untuk menentukan urutan operasi. Tanpa tanda kurung,5 kali 4 kali 2akan dianggap ambigu dan ditolak kompilator.
Syarat Deklarasi #
Tiga syarat wajib agar sebuah function dapat ditandai infix:
- menjadi member function dari class atau extension function pada tipe tertentu
- menerima tepat satu parameter (boleh memiliki default value, tetapi jumlahnya satu)
- parameter tidak boleh
varargdan tidak boleh menerima jumlah argumen variabel
Syarat tersebut menjaga sintaks infix tetap sederhana: bentuk a op b memerlukan dua operand dan satu operator.
class Wadah(val nilai: Int) {
infix fun gabung(lain: Wadah): Wadah = Wadah(this.nilai + lain.nilai)
}
fun main() {
val a = Wadah(10)
val b = Wadah(20)
val c = a gabung b
println(c.nilai)
}Member function gabung di dalam class Wadah juga dapat ditandai infix. Pemanggilan a gabung b setara dengan a.gabung(b).
Aturan Precedence dan Associativity #
Infix function memiliki precedence yang sama dengan operator perkalian dan pembagian. Bila dua infix function berdekatan, kompilator wajib diberi tanda kurung untuk menentukan urutan operasi. Tanpa tanda kurung, kompilator melaporkan galat ambigu.
infix fun Int.tambah(n: Int): Int = this + n
infix fun Int.kurang(n: Int): Int = this - n
fun main() {
val a = (10 tambah 5) kurang 3 // valid: hasil 12
val b = 10 tambah (5 kurang 3) // valid: hasil 12
// val c = 10 tambah 5 kurang 3 // GALAT: ambigu
}Pemanggilan yang ditandai komentar di atas menimbulkan galat karena kompilator tidak tahu apakah 5 menjadi argumen tambah atau kurang. Tanda kurung eksplisit menyelesaikan ambiguitas tersebut.
Kapan Menggunakan infix #
Infix function paling cocok untuk operasi yang secara semantik mirip dengan operator — misalnya kali, ditambah, kepada, hingga. Bila sebuah function melakukan tugas kompleks dengan banyak efek samping, bentuk pemanggilan reguler dengan titik dan kurung sering kali lebih jelas.
infix fun Int.ke(batas: Int): IntRange = this..batas // Tepat: mirip operator rentang
infix fun String.kirimKe(email: String): Unit { // Kurang tepat: efek samping IO
println("Mengirim '$this' ke $email")
}ke terasa natural sebagai operator, sedangkan kirimKe yang mengakibatkan efek samping IO lebih baik dipanggil dalam bentuk reguler agar pembaca menyadari adanya aksi non-trivial.
Referensi Lanjutan #
- Kotlin functions
— panduan resmi
infixfunction untuk notasia op b
Ringkasan #
Infix function memungkinkan pemanggilan dengan bentuk a op b yang terbaca seperti kalimat. Function demikian harus member atau extension function dengan tepat satu parameter. Tanda kurung wajib dipakai saat memanggil infix secara berantai. Pada chapter operator Functions berikutnya, kita akan melihat bagaimana Kotlin memungkinkan kita mendefinisikan ulang operator seperti +, *, dan in menggunakan keyword operator.