Dalam banyak bahasa turunan C, if dan try adalah statement yang mengatur alur kontrol tanpa menghasilkan nilai. Kotlin mengubah peran ini: if, when, try, throw, dan beberapa konstruksi lain adalah expression yang mengembalikan nilai. Perbedaan ini tampak sederhana, tetapi mengubah cara kita menulis kode idiomatis. Pada chapter ini kita akan membandingkan pendekatan Kotlin dengan Java, melihat contoh if dan when sebagai expression, lalu membahas batasan dan praktik terbaiknya.

Apa itu Expression dan Statement #

Perbedaan utama antara keduanya:

IstilahDefinisiContoh di Kotlin
ExpressionKonstruksi yang menghasilkan nilaia + b, if (x > 0) 1 else -1
StatementKonstruksi yang melakukan aksi, tidak menghasilkan nilaival x = 5, return, while (cond) { ... }

Beberapa konstruksi di Kotlin bersifat hibrida: dapat dipakai sebagai expression maupun statement tergantung konteks. Yang paling penting: if, when, try, dan throw selalu merupakan expression, sehingga kita dapat menulis val result = if (...) ... else ... tanpa blok prosedural tambahan.

if dan when sebagai Expression #

kotlin
fun main() {
    val suhu = 38

    val status = if (suhu > 37) "demam" else "normal"
    println("Status suhu: $status")

    val pesan = when {
        suhu > 37 -> "Periksa ke dokter"
        suhu < 35 -> "Suhu rendah"
        else -> "Sehat"
    }
    println("Pesan: $pesan")

    val angka = 7
    val jenis = when (angka % 2) {
        0 -> "genap"
        else -> "ganjil"
    }
    println("$angka adalah $jenis")

    val hasil: Int = try {
        "123".toInt()
    } catch (e: NumberFormatException) {
        0
    }
    println("Hasil parsing: $hasil")

    val tinggi = 175
    val kategori = if (tinggi > 170) {
        println("Tinggi di atas rata-rata")
        "tinggi"
    } else {
        "sedang"
    }
    println("Kategori: $kategori")

    val diskon = if (angka > 5) 10 else 5
    val total = 100 - diskon
    println("Diskon: $diskon%, total bayar: $total")

    val kode = 200
    val label = when (kode) {
        in 200..299 -> "sukses"
        in 300..399 -> "redirect"
        in 400..499 -> "klien error"
        else -> "server error"
    }
    println("HTTP $kode: $label")
}

Output yang Dihasilkan:

text
Status suhu: demam
Pesan: Periksa ke dokter
7 adalah ganjil
Hasil parsing: 123
Tinggi di atas rata-rata
Kategori: tinggi
Diskon: 10%, total bayar: 90
HTTP 200: sukses

Mari kita bedah setiap konstruksi pada contoh di atas:

  1. val status = if (suhu > 37) "demam" else "normal" menunjukkan if sebagai expression. Cabang then dan else mengembalikan string, lalu string tersebut ditugaskan ke status. Tanpa fitur ini, kita harus menulis var status: String; if (...) status = ... else status = ... yang lebih bertele-tele.
  2. val pesan = when { ... } menunjukkan when sebagai expression. Setiap cabang mengembalikan string. Cabang else wajib bila when dipakai sebagai expression dengan tipe non-Unit, agar kompilator yakin semua jalur mengembalikan nilai.
  3. when (angka % 2) { 0 -> "genap"; else -> "ganjil" } menggunakan when dengan subject. Cabang dievaluasi berurutan; cabang pertama yang cocok diambil, sisanya diabaikan. Ekspresi ini menggantikan switch di Java dengan sintaks yang lebih ringkas dan tanpa break.
  4. val hasil: Int = try { ... } catch (...) { 0 } menunjukkan try sebagai expression. Blok try mengembalikan nilai dari baris terakhirnya ("123".toInt() = 123). Bila exception dilempar, cabang catch mengembalikan 0.
  5. val kategori = if (...) { println(...); "tinggi" } else { "sedang" } menunjukkan bahwa setiap cabang if dapat memuat blok multi-baris. Baris terakhir pada blok menjadi nilai kembalian expression. Di dalam blok, kita dapat melakukan efek samping seperti mencetak log sebelum mengembalikan nilai.
  6. val diskon = if (angka > 5) 10 else 5 menunjukkan if-expression inline yang sangat ringkas. Pola ini menggantikan operator ternary ?: di Java. Kotlin sengaja tidak memiliki operator ternary karena if-else sudah cukup ringkas.
  7. when (kode) { in 200..299 -> "sukses" ... } menunjukkan when dengan cabang rentang. Setiap cabang dapat memuat pemeriksaan tipe, rentang, multiple value, atau kondisi kompleks. when di Kotlin jauh lebih ekspresif dibanding switch di Java.

Perbandingan dengan Java #

Berikut perbandingan gaya penulisan if di Kotlin dan Java:

kotlin Kotlin: if sebagai expression
val status = if (suhu > 37) "demam" else "normal"
java Java: if sebagai statement (tidak mengembalikan nilai)
String status;
if (suhu > 37) {
    status = "demam";
} else {
    status = "normal";
}

Versi Kotlin lebih ringkas karena if langsung mengembalikan nilai. Versi Java memerlukan deklarasi variabel terlebih dahulu, lalu pengisian nilai pada setiap cabang. Hal yang sama berlaku untuk switch di Java: tidak dapat mengembalikan nilai, sehingga pengisian variabel harus dilakukan di setiap case.

Batasan dan Praktik Terbaik #

Beberapa batasan penting ketika memakai if/when/try sebagai expression:

KonstruksiBoleh mengembalikan nilai?Catatan
if dengan elseYaTipe kembalian adalah supertype tipe cabang
if tanpa elseHanya UnitTidak menghasilkan nilai
when dengan elseYaSama seperti if
when tanpa else (exhaustive)YaHanya untuk enum/sealed class/Boolean
try dengan catchYaSetiap cabang harus mengembalikan tipe kompatibel
try tanpa catchYaSama seperti blok biasa
throwYa (tipe Nothing)Tidak pernah benar-benar mengembalikan nilai

Tipe Nothing menandakan ekspresi yang tidak pernah selesai normally. Karena throw melempar exception, ekspresi throw Exception() bertipe Nothing. Hal ini berguna untuk cabang when yang seharusnya tidak pernah tercapai, karena Nothing adalah subtype dari semua tipe lain sehingga kompilator menerima cabang tersebut tanpa keluhan.

Gaya Idiomatis Kotlin #

Mengandalkan if/when/try sebagai expression adalah ciri khas gaya Kotlin. Bila menemukan diri menulis var x: T; if (...) x = ... else x = ..., hentikan sejenak dan pertimbangkan untuk menulis ulang sebagai val x = if (...) ... else .... Versi val lebih aman karena variabel tidak dapat diubah setelah inisialisasi, dan kompilator dapat melakukan smart cast dengan lebih baik.

Referensi Lanjutan #

Dengan pemahaman tentang expression dan statement, kita menutup section operator-dan-ekspresi. Pada section berikutnya, kita akan beralih ke topik input/output dan formatting yang memungkinkan program Kotlin berinteraksi dengan pengguna melalui terminal.