Function Inside Function didalam Kotlin
Ketika mengembangkan sebuah proyek, kita pasti membuat beberapa fungsi tersendiri dengan tujuan untuk memisahkan logika program dari fungsi utama.
Tujuannya adalah agar kode lebih terstruktur dan mudah dibaca. Namun pada praktiknya, terkadang kode yang ada pada fungsi tersebut malah lebih panjang dan susah dibaca. Salah satu penyebabnya adalah karena penulisan kode yang berulang atau lainnya.
Untuk mengatasinya, kita bisa memisahkannya lagi menjadi sebuah fungsi lokal (inner function) dengan hak akses terbatas hanya untuk fungsi terluarnya. Ini bisa dilakukan karena pada Kotlin kita bisa mendefinisikan sebuah fungsi di mana pun, bahkan di dalam sebuah fungsi (function inside function).
Berikut adalah contoh dari sebuah inner function:
- fun setWord(message: String) {
- fun printMessage(text: String) {
- println(text)
- }
- printMessage(message)
- }
Bisa diperhatikan bahwa fungsi printMessage() didefinisikan di dalam fungsi setWord(). Mendefinisikan sebuah inner function sama halnya seperti kita mendefinisikan sebuah fungsi seperti biasanya. Menariknya, kita bisa mengakses apa yang menjadi bagian fungsi terluarnya. Contoh, parameter dari fungsi setWord() bisa diakses dari dalam fungsi print sehingga kode di atas bisa diubah menjadi seperti berikut:
- fun setWord(message: String) {
- fun printMessage() {
- println(message)
- }
- printMessage()
- }
Lebih sederhana bukan? Perlu diperhatikan, inner function hanya bisa diakses setelah fungsi tersebut didefinisikan. Jika kita coba mengaksesnya, maka akan tampil eror seperti berikut:
- fun setWord(message: String) {
- printMessage() // ERROR: Unresolved references
- fun printMessage() {
- println(message)
- }
- printMessage()
- }
Lalu, pada kondisi seperti apa kita bisa memanfaatkan inner function? Perhatikan deklarasi fungsi berikut di bawah ini:
- fun sum(valueA: Int, valueB: Int, valueC: Int): Int {
- if (valueA == 0) {
- throw IllegalArgumentException("valueA must be better than 0")
- }
- if (valueB == 0) {
- throw IllegalArgumentException("valueB must be better than 0")
- }
- if (valueC == 0) {
- throw IllegalArgumentException("valueC must be better than 0")
- }
- return valueA + valueB
- }
Tidak ada yang salah dengan semua fungsi di atas. Fungsi tersebut akan berjalan dengan semestinya tanpa adanya eror selama kondisi yang berada di dalamnya tidak terpenuhi. Namun jika kita perhatikan, terdapat pengulangan kode yang sama yaitu penggunaan if expression untuk memeriksa apakah nilai dari argumen yang diberikan bernilai null.
Di sinilah kita bisa memanfaatkan inner function untuk membuat kode yang ditulis berulang tersebut menjadi fungsi tersendiri.
- fun sum(valueA: Int, valueB: Int, valueC: Int): Int {
- fun validateNumber(value: Int) {
- if (value == 0) {
- throw IllegalArgumentException("value must be better than 0")
- }
- }
- validateNumber(valueA)
- validateNumber(valueB)
- validateNumber(valueC)
- return valueA + valueB
- }
Setelah menjadikannya sebagai sebuah fungsi tersendiri, kode yang ada di dalam fungsi sum() tersebut lebih singkat dan tentunya lebih mudah dibaca dibandingkan sebelumnya.
Selain itu, kita juga bisa menjadikan inner function sebagai extensions function. Contohnya seperti berikut:
Selain itu, kita juga bisa menjadikan inner function sebagai extensions function. Contohnya seperti berikut:
- fun sum(valueA: Int, valueB: Int, valueC: Int): Int {
- fun Int.validateNumber(){
- if (this == 0) {
- throw IllegalArgumentException("value must be better than 0")
- }
- }
- valueA.validateNumber()
- valueB.validateNumber()
- valueC.validateNumber()
- return valueA + valueB
- }