Setiap function di Kotlin wajib mendeklarasikan apa yang dikembalikan ke pemanggil, baik secara eksplisit maupun implisit. Tiga kemungkinan utama: tipe konkret seperti Int atau String, tipe Unit untuk function yang hanya menjalankan efek samping, dan tipe Nothing untuk function yang tidak pernah kembali ke pemanggil. Pada chapter ini kita akan membedah ketiganya beserta implikasinya terhadap kompilator.

Tipe Konkret: Hasil yang Dapat Digunakan #

Function yang mengembalikan tipe konkret wajib menuliskan tipe tersebut setelah tanda titik dua, dan wajib memiliki paling sedikit satu pernyataan return yang menghasilkan nilai kompatibel. Berikut contoh function yang mengembalikan Int.

kotlin
fun kali(a: Int, b: Int): Int {
    return a * b
}

fun cetakHeader(judul: String) {
    println("=== $judul ===")
}

fun gagalDengan(pesan: String): Nothing {
    throw IllegalStateException(pesan)
}

fun main() {
    cetakHeader("Demonstrasi Return Type")
    val hasil = kali(7, 6)
    println("7 x 6 = $hasil")

    val data: Unit = cetakHeader("Unit tidak membawa nilai")
    println("Nilai yang dikembalikan: $data")
}

Output yang Dihasilkan:

text
=== Demonstrasi Return Type ===
7 x 6 = 42
=== Unit tidak membawa nilai ===
Nilai yang dikembalikan: kotlin.Unit

Mari kita bedah baris per baris:

  1. fun kali(a: Int, b: Int): Int: tipe kembalian Int ditulis setelah tanda titik dua. Body wajib berisi return yang menghasilkan Int.
  2. fun cetakHeader(judul: String): tidak ada tipe kembalian ditulis. Kotlin menyimpulkan Unit. Function ini menjalankan efek samping (mencetak) tanpa membawa nilai kembali.
  3. fun gagalDengan(pesan: String): Nothing: tipe kembalian Nothing. Function ini selalu melempar exception sehingga tidak pernah kembali ke pemanggil dengan normal.
  4. val data: Unit = cetakHeader(...): pemanggil menangkap nilai Unit ke variabel data. Nilai Unit hanya satu yaitu kotlin.Unit.

Unit: Tipe Tanpa Nilai #

Unit adalah tipe dengan tepat satu nilai, yaitu Unit. Tipe ini setara dengan void di Java, tetapi Unit tetap merupakan nilai konkret sehingga dapat disimpan ke variabel atau dijadikan argumen function. Setiap function yang tidak menyatakan tipe kembalian eksplisit otomatis mengembalikan Unit.

kotlin Contoh: tiga bentuk function Unit yang setara
fun sapaA(nama: String): Unit {
    println("Halo, $nama")
}

fun sapaB(nama: String) {
    println("Halo, $nama")
}

fun sapaC(nama: String): Unit = println("Halo, $nama")

Ketiga deklarasi di atas mengembalikan Unit. Bentuk sapaB adalah yang paling umum dipakai karena ringkas. Bentuk sapaA terlalu eksplisit dan jarang diperlukan. Bentuk sapaC memakai single-expression yang akan kita bahas pada chapter berikutnya.

Nothing: Tipe yang Tidak Pernah Kembali #

Nothing adalah tipe khusus yang menandai function tidak pernah kembali ke pemanggil secara normal. Function demikian hanya boleh berakhir dengan melempar exception atau menjalankan loop tak terhingga. Kegunaan praktis Nothing terlihat pada function utilitas seperti fail() yang melempar exception sebagai jalan keluar terakhir.

kotlin Contoh: pola fail() yang mengembalikan Nothing
fun fail(pesan: String): Nothing {
    throw IllegalStateException(pesan)
}

fun ambilNama(daftar: List<String>): String {
    if (daftar.isEmpty()) {
        fail("Daftar nama kosong")
    }
    return daftar[0]
}

Karena fail() mengembalikan Nothing, kompilator tahu bahwa jalur kode setelah pemanggilan fail() tidak akan pernah dieksekusi. Akibatnya, blok if di atas dianggap selalu mengembalikan String, dan deklarasi return daftar[0] di luar if tetap valid meskipun secara sintaksis tidak diperlukan.

Return Tunggal, Bukan Banyak Nilai #

Sebuah function hanya dapat mengembalikan satu nilai. Bila kita ingin mengembalikan beberapa nilai sekaligus, gunakan Pair, Triple, atau data class. Pendekatan ini menjaga kontrak function tetap sederhana dan terprediksi.

kotlin Contoh: mengembalikan banyak nilai dengan Pair
fun minMaks(data: List<Int>): Pair<Int, Int> {
    var min = data[0]
    var maks = data[0]
    for (n in data) {
        if (n < min) min = n
        if (n > maks) maks = n
    }
    return Pair(min, maks)
}

Pemanggil dapat menangkap hasil dengan destructuring: val (min, maks) = minMaks(data). Pola ini akan kita bahas lebih lanjut pada section Object-Oriented Programming.

Referensi Lanjutan #

Ringkasan #

Return type menentukan kontrak keluaran function. Tipe konkret mengharuskan body mengandung return kompatibel. Unit adalah default bila tipe tidak ditulis. Nothing menandai function yang tidak pernah kembali normal dan membantu kompilator menganalisis alur kode. Pada chapter Single-Expression Functions berikutnya, kita akan melihat cara memendekkan deklarasi function menjadi satu baris ekspresi tanpa kurung kurawal.