Scope Functions adalah function-function bawaan dari Kotlin yang bisa kita gunakan untuk mengeksekusi block kode di dalam scope sebuah object. dan di dalam scope tersebut kita bisa mengakses objectnya tanpa perlu menyebutkan namanya secara eksplisit.
Scope function sebenarnya tidak memberikan pengaruh apapun secara behavior, kita bisa saja menulis kode tanpa menggunakan scope function sama sekali. Namun dengan scope function, kode kita akan menjadi lebih ringkas dan mudah untuk dibaca.
Di Kotlin, terdapat 5 scope function yaitu let, with, run, apply, dan also. Kelima function tersebut mempunyai banyak kemiripan, sehingga kita kadang sulit untuk membedakannya.
Nah, di artikel kali ini kita akan belajar apa saja sih perbedaan dari masing-masing function tersebut serta dalam case seperti apa kita akan menggunakannya.
Agar lebih mudah dalam membedakan Scope Functions, kita perlu mengetahui karakteristik-karakteristik nya terlebih dahulu. berikut adalah 3 karakteristik dari Scope Functions:
Ada 2 jenis pemanggilan Scope Functions, tergantung apakah Scope Functions tersebut merupakan Extension atau bukan.
Jika Scope Functions tersebut merupakan Extension maka kita panggil dengan dot lalu diikuti nama functionnya. Contohnya seperti ini:
1val name: String? = "kotlin"23name?.let {4 println(it.length)5}
Berikut adalah Scope Functions yang merupakan Extension: let, run, apply, also
Tapi jika bukan Extension, kita tinggal panggil saja seperti function biasa. Contohnya seperti ini:
1val name = "kotlin"23with(name) {4 println(length)5 println(reversed())6}
Berikut adalah Scope Functions yang bukan merupakan Extension: run, with
Khusus Scope Function run, ada 2 cara untuk pemanggilannya, yaitu dengan cara dipanggil langsung atau melalui Extension.
Context Object merupakan object yang tersedia di dalam lambda pada Scope Functions. Kita bisa mengakses object tersebut menggunakan this atau it. Berikut adalah kelebihan dan kekurangan dari kedua cara pengaksesan tersebut:
Kelebihan: Kita bisa mengakses properti dan method yang terdapat pada object this secara langsung tanpa perlu menuliskan this.
Kekurangan: Karena kita bisa mengakses secara langsung, jadi agak rancu apakah properti dan method yang kita akses itu apakah berasal dari object this atau berasal dari luar lambda?
Jadi, object reference this cocok digunakan jika di dalam lambda-nya kebanyakan hanya menggunakan properti & method milik dari object this saja.
Berikut adalah Scope Functions yang menggunakan object reference this:
run
with
apply
Kelebihan: Secara penulisan lebih singkat dari this, jadi akan lebih mudah untuk dibaca.
Kekurangan: Kita tidak bisa mengakses properti & method yang terdapat pada it secara langsung.
Jadi, object reference it cocok digunakan jika di dalam lambda-nya banyak menggunakan properti atau method dari luar Scope Functions.
Jika kamu mau, kamu juga bisa mengubah nama variabel it menjadi apapun yang kamu inginkan, contohnya seperti ini:
1Random.nextInt(100).also { randomValue ->2 println(randomValue)3}
Berikut adalah Scope Functions yang menggunakan object reference it:
let
also
Kita juga perlu memperhatikan apa yang dikembalikan dari Scope Function yang ingin kita pakai, Apakah kita ingin yang dikembalikan adalah Context Object-nya atau hasil dari lambda kita (Lambda Result) ?
Berikut adalah Scope Functions yang mengembalikan Context Object: apply, also
1val numberList = mutableListOf<Int>(1, 3, 2)2numberList3 .also { println("Sorting the list...") }4 .sort()5 .also { println("Sorted! ✅") }67println(numberList)89// RESULT:10// Sorting the list...11// Sorted! ✅12// [1, 2, 3]
Berikut adalah Scope Functions yang mengembalikan hasil dari lambda kita: let, run, with
1val animals = mutableListOf("🐥", "🐒", "🐥")2val totalDucks = animals.run {3 add("🐥")4 add("🐥")5 count { it == "🐥" }6}7println("There are $totalDucks ducks.")89// RESULT:10// There are 4 ducks.
Setelah mengetahui karakteristik dari Scope Functions, kita akan belajar lebih detail terkait masing-masing dari Scope Functions serta contoh penggunaannya.
Extension
Context Object: it
Return Value: Lambda Result
Scope Function let biasanya digunakan jika kita ingin melakukan sesuatu terhadap sebuah nullable object (object yang valuenya bisa null) dan kita ingin menghindari NullPointException.
Perhatikan contoh berikut:
1val name: String? = "kotlin"2// val total = count(name) // ERROR: Type mismatch3val total = name?.let {4 println(it.reversed())5 count(it) // OK6}78fun count(string: String): Int = string.length
Dengan menggunakan Scope Functions let, di dalam lambda-nya kita tidak perlu lagi menggunakan Safe Call Operator (?.) tiap kali kita mengakses variabel name.
Jika di dalam lambda let hanya memanggil 1 function saja dan function tersebut menerima it sebagai argumen, kamu bisa menggunakan method reference (::) untuk memperingkas kode.
2val total = name?.let(::count)34fun count(): Int = "string".length
Bukan Extension
Context Object: this
Return Value: Lambda Result
Scope Function with biasanya digunakan untuk melakukan grouping pemanggilan function pada suatu variabel.
Contoh penggunaannya seperti ini:
1val name = "kotlin"2with(name) {3 println("The reversed of $this is ${reversed()}")4}56// RESULT:7// The reversed of kotlin is niltok
Extension & Bukan Extension
Context Object: this
Return Value: Lambda Result
Scope Function run biasanya digunakan untuk melakukan inisialisasi object.
run mempunyai 2 cara untuk pemanggilannya, yaitu dengan cara dipanggil langsung atau melalui Extension.
Contoh penggunaannya seperti ini:
1val httpClient = HttpClient()23// Extension4val devHttpClient = httpClient.run {5 baseURL = "http://dev.api.com"6 timeout = 50007}89// Bukan Extension10val productionHttpClient = run {11 val baseURL = "http://backend.com"12 val timeout = 500013 HttpClient(baseURL, timeout)14}1516class HttpClient(17 var baseURL: String? = null,18 var timeout: Int? = null19)
Extension
Context Object: this
Return Value: Context Object
Scope Function apply biasanya digunakan untuk melakukan konfigurasi object.
1val httpClient = HttpClient("http://backend.com")23httpClient.apply {4 timeout = 10_0005}
Extension
Context Object: it
Return Value: Context Object
Scope Function also biasanya digunakan untuk melakukan suatu action ketika sebuah object telah diinisialisasi. Misalnya seperti logging, tracker, dll.
Berikut adalah contoh penggunaannya:
1val numberList = mutableListOf<Int>(1, 3, 2)2numberList3 .also { println("Sorting the list...") }4 .sort()5 .also { println("Sorted! ✅") }67println(numberList)89// RESULT:10// Sorting the list...11// Sorted! ✅12// [1, 2, 3]
Agar lebih mudah dalam mengingat dan memahami perbedaan dari masing-masing Scope Functions, kamu bisa mengacu pada tabel berikut:
Scope Function | Object Reference | Return Value | Apakah Extension? |
---|---|---|---|
let | it | Lambda Result | Ya |
with | this | Lambda Result | Bukan Extension |
run | this | Lambda Result | Ya |
run | - | Lambda Result | Bukan Extension |
apply | this | Context Object | Ya |
also | it | Context Object | Ya |
Oke mungkin itu saja yang bisa saya bagikan kali ini, kalau kamu merasa artikel ini bermanfaat silakan Like & Share artikel ini ke teman-teman kamu atau jika kamu punya pertanyaan, tulis aja di kolom komentar, Thank you! 😁 🙏
Always open to new ideas. 🕊️
Articles that you might want to read.
Membuat custom Domain Specific Language (DSL) pada Kotlin.
Tutorial Object Detection menggunakan Create ML dan Vision Framework.
Memahami Method Swizzling pada Swift.