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:
| Istilah | Definisi | Contoh di Kotlin |
|---|---|---|
| Expression | Konstruksi yang menghasilkan nilai | a + b, if (x > 0) 1 else -1 |
| Statement | Konstruksi yang melakukan aksi, tidak menghasilkan nilai | val 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 #
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:
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: suksesMari kita bedah setiap konstruksi pada contoh di atas:
val status = if (suhu > 37) "demam" else "normal"menunjukkanifsebagai expression. Cabangthendanelsemengembalikan string, lalu string tersebut ditugaskan kestatus. Tanpa fitur ini, kita harus menulisvar status: String; if (...) status = ... else status = ...yang lebih bertele-tele.val pesan = when { ... }menunjukkanwhensebagai expression. Setiap cabang mengembalikan string. Cabangelsewajib bilawhendipakai sebagai expression dengan tipe non-Unit, agar kompilator yakin semua jalur mengembalikan nilai.when (angka % 2) { 0 -> "genap"; else -> "ganjil" }menggunakanwhendengan subject. Cabang dievaluasi berurutan; cabang pertama yang cocok diambil, sisanya diabaikan. Ekspresi ini menggantikanswitchdi Java dengan sintaks yang lebih ringkas dan tanpabreak.val hasil: Int = try { ... } catch (...) { 0 }menunjukkantrysebagai expression. Bloktrymengembalikan nilai dari baris terakhirnya ("123".toInt()=123). Bila exception dilempar, cabangcatchmengembalikan0.val kategori = if (...) { println(...); "tinggi" } else { "sedang" }menunjukkan bahwa setiap cabangifdapat 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.val diskon = if (angka > 5) 10 else 5menunjukkan if-expression inline yang sangat ringkas. Pola ini menggantikan operator ternary?:di Java. Kotlin sengaja tidak memiliki operator ternary karenaif-elsesudah cukup ringkas.when (kode) { in 200..299 -> "sukses" ... }menunjukkanwhendengan cabang rentang. Setiap cabang dapat memuat pemeriksaan tipe, rentang, multiple value, atau kondisi kompleks.whendi Kotlin jauh lebih ekspresif dibandingswitchdi Java.
Perbandingan dengan Java #
Berikut perbandingan gaya penulisan if di Kotlin dan Java:
val status = if (suhu > 37) "demam" else "normal"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:
| Konstruksi | Boleh mengembalikan nilai? | Catatan |
|---|---|---|
if dengan else | Ya | Tipe kembalian adalah supertype tipe cabang |
if tanpa else | Hanya Unit | Tidak menghasilkan nilai |
when dengan else | Ya | Sama seperti if |
when tanpa else (exhaustive) | Ya | Hanya untuk enum/sealed class/Boolean |
try dengan catch | Ya | Setiap cabang harus mengembalikan tipe kompatibel |
try tanpa catch | Ya | Sama seperti blok biasa |
throw | Ya (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 #
- Operator overloading — konteks expression pada konvensi operator Kotlin
- Unit API reference
— API reference
Unitsebagai tipe kembalian statement
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.