let adalah scope function paling sering dipakai untuk null-safety dan transformasi nilai. Function ini memberi akses ke objek via parameter implisit it dan mengembalikan hasil block sebagai nilai kembalian. Pada chapter ini kita akan membedah empat pola penggunaan let yang umum di kode Kotlin modern — null-safety via safe-call, transformasi nilai, scope variabel lokal, dan rename it. Kita juga akan melihat kapan let tidak diperlukan agar tidak dipakai berlebihan.
Apa Itu let #
let adalah extension function dengan signature:
inline fun <T, R> T.let(block: (T) -> R): R- Receiver: objek yang dipanggil
let(tersedia di block sebagaiit). - Return: hasil block
block(it), bertipeR. - Use case utama: null-safety, transformasi nilai.
Tabel Perbandingan let dengan Scope Lain #
| Aspek | let |
|---|---|
| Receiver | it (parameter implisit) |
| Return | lambda result |
| Idiomatic use | Null-safety, transformasi |
| Bisa safe-call | Ya — obj?.let { ... } |
Pola let di Kode Nyata #
Mari kita lihat empat pola let yang sering muncul.
// let_example.kt
// let: receiver `it`, mengembalikan lambda result.
// Cocok untuk null-safety dan transformasi.
data class Pengguna(val nama: String, val umur: Int)
fun temukanPengguna(id: Int): Pengguna? {
return if (id == 1) Pengguna("Budi", 25) else null
}
fun main() {
// Pola 1: null-safety dengan safe-call + let.
val hasil = temukanPengguna(1)
hasil?.let { pengguna ->
println("Ditemukan: ${pengguna.nama}, ${pengguna.umur} tahun")
}
val hasilKosong = temukanPengguna(99)
hasilKosong?.let {
println("Tidak akan tercetak")
} ?: println("Pengguna tidak ditemukan")
// Pola 2: transformasi nilai.
val pesan = "Halo"
val panjang = pesan.let { it.length }
println("Panjang \"$pesan\": $panjang")
// Pola 3: scope variabel lokal untuk menghindari pengulangan.
val pengguna = Pengguna("Siti", 30)
val info = pengguna.let {
val status = if (it.umur >= 17) "dewasa" else "anak"
"${it.nama} ($status)"
}
println("Info: $info")
// Pola 4: rename `it` untuk kejelasan.
val nomor = 42
val deskripsi = nomor.let { n -> "angka favorit: $n" }
println(deskripsi)
// Perbandingan: tanpa let.
val nama = "Andi"
val sapa = "Halo, $nama!" // tidak ada manfaat let di sini
println(sapa)
}Output yang Dihasilkan:
Ditemukan: Budi, 25 tahun
Pengguna tidak ditemukan
Panjang "Halo": 4
Info: Siti (dewasa)
angka favorit: 42
Halo, Andi!Mari kita telaah baris-baris kode di atas:
- Baris 8-10 (
fun temukanPengguna(id: Int): Pengguna?): function mengembalikanPengguna?— bisa null. Polaletdipakai untuk menangani hasil dengan aman. - Baris 14-17 (
hasil?.let { pengguna -> println(...) }): pola null-safety. Safe-call?.memastikanlethanya dipanggil bilahasiltidak null. Di dalam block,penggunaadalah instance non-null. Bila null, block tidak dijalankan. - Baris 19-22 (
hasilKosong?.let { ... } ?: println(...)): gabunganletdengan elvis operator?:. BilahasilKosongnull, blockletdi-skip dan blok?:dijalankan. Pola umum untuk “jika null, lakukan fallback”. - Baris 25 (
val panjang = pesan.let { it.length }): pola transformasi.letmengubahStringmenjadiInt(panjang). Block mengembalikanit.lengthyang menjadi nilaipanjang. - Baris 29-33 (
val info = pengguna.let { ... }): pola scope variabel lokal. Di dalam block, kita buatval statuslokal yang hanya bisa diakses di dalam block. Hasil block adalah string ringkasan. Manfaat:statustidak bocor ke scope luar. - Baris 37 (
val deskripsi = nomor.let { n -> "angka favorit: $n" }): pola renameit. Bilaitkurang jelas, kita beri namaneksplisit. Berguna saat body panjang atau konteks memerlukan nama deskriptif. - Baris 41-43 (
val sapa = "Halo, $nama!"): contoh di manalettidak diperlukan. String template sudah cukup ringkas. Menambahletdi sini hanya menambah noise tanpa manfaat.
Kapan Tidak Memakai let #
let sering disalahgunakan untuk “menjelaskan” kode yang sebetulnya sudah jelas. Beberapa tanda let berlebihan:
- Block hanya berisi satu pemanggilan method —
obj.let { it.foo() }lebih baik ditulisobj.foo(). - Block hanya berisi string template —
obj.let { "$it" }lebih baik ditulis"$obj". - Block tidak menggunakan nilai kembalian apa pun.
let untuk Reduksi Pengulangan #
Saat kita sering memanggil property atau method pada objek yang sama, let dapat mengurangi pengulangan dengan menyediakan nama singkat:
val pengguna = ambilPengguna()
val sapaan = pengguna.let { "${it.nama} - ${it.umur} - ${it.kota}" }Tanpa let, kita menulis pengguna.nama, pengguna.umur, pengguna.kota — tiga kali prefix. let tidak wajib di sini, tetapi dapat membantu bila objek dari ekspresi panjang.
Referensi Lanjutan #
- Scope functions
— panduan resmi
letuntuk null-safety dan transformasi - Higher-order functions and lambdas
— dasar lambda pada
let
Penutup #
let adalah scope function paling sering dipakai untuk null-safety dan transformasi nilai. Dengan pola obj?.let { ... }, kita menjalankan block hanya bila objek non-null — menghindari null check eksplisit. let juga berguna untuk membentuk scope variabel lokal yang tidak bocor keluar. Selanjutnya, kita akan mempelajari run — scope function yang menggunakan this sebagai receiver dan cocok untuk eksekusi block pada objek dengan kembalian hasil.