Careeroza
Choosing a Scope Function
Decision Guide
Do you need the object back (builder / chain)?
yes -> refers to it as this? apply (configure)
refers to it as it? also (log / validate)
no -> null check / transform with it? let
call many members, compute result? run (or with(obj) for a non-null object)takeIf and takeUnless
Example
takeIf returns the object if the condition is true, otherwise null. It pairs nicely with ?.let and ?:.
fun main() {
val input = " coupon50 "
val code = input.trim().takeIf { it.length >= 6 }?.uppercase()
println(code)
val age = 15
val canVote = age.takeUnless { it < 18 }?.let { "Eligible" } ?: "Not eligible"
println(canVote)
}Output
COUPON50 Not eligible
Do Not Overuse
Note: Nesting scope functions (a?.let { b.run { c.also { } } }) quickly becomes unreadable, and it/this become ambiguous. If a plain if or a local val is clearer, use that.
Exercise: Rewrite using apply and also: create a MutableList<String>, add "A" and "B", print its size, then return it.
Show answer
val list = mutableListOf<String>()
.apply { add("A"); add("B") }
.also { println("Size: ${it.size}") }