Scope Functions Workbook
Practice problems for let, run, apply, also, with. Each takes a minute or two. Write your own answer first, then click Show answer — nothing here is a trick question, just direct practice of the syntax from the lesson.
the two questions
1. Configure and return
Create a StringBuilder, append "a" and "b", and keep the builder — using the scope function meant for configuration.
Show answer Hide answer
val sb = StringBuilder().apply {
append("a")
append("b")
}apply: receiver is this, returns the object.
2. Do this if not null
Given name: String?, send a welcome to it only when it isn’t null.
Show answer Hide answer
name?.let { sendWelcome(it) }let: object is it, returns the block’s result.
3. Side effect in a chain
Given loadUser(), log the user and return it unchanged, in one chained call.
Show answer Hide answer
loadUser().also { println("loaded $it") }also: object is it, returns the object.
4. Compute from members
Given a rectangle with width and height, compute its area with a scope function that exposes the object as this and returns the result.
Show answer Hide answer
val area = rectangle.run { width * height } 5. Group operations on one object
Given canvas, call drawLine(...) and drawCircle(...) on it without repeating canvas, using the non-extension form.
Show answer Hide answer
with(canvas) {
drawLine(0, 0, 10, 10)
drawCircle(5, 5, 3)
} takeIf and choosing
6. Keep it only if it qualifies
Given input: String, return it only if it’s not blank, otherwise return from the function.
Show answer Hide answer
val value = input.takeIf { it.isNotBlank() } ?: returntakeIf returns the object or null, so it chains with Elvis.
7. Keep unless
Given input: String, return it unless it’s blank (in which case null), using a single scope function.
Show answer Hide answer
input.takeUnless { it.isBlank() }takeUnless is takeIf’s negation — it keeps the object only when the condition is false.
8. Build and assign
Create a mutableListOf<Int>(), add 1 and 2 to it, and assign the resulting list to nums — using the scope function that returns the object.
Show answer Hide answer
val nums = mutableListOf<Int>().apply {
add(1)
add(2)
}apply returns the object (the list), so the whole expression is assignable; also is its it-based counterpart.
9. Swap this for it
Rewrite rectangle.run { width * height } using let instead, so the object is referred to as it.
Show answer Hide answer
rectangle.let { it.width * it.height }run exposes the object as this; let exposes it as it.
10. Combine two in a chain
Given a fresh Request(url), set its method = "POST" and then log it — using apply then also in a single chain that ends holding the request.
Show answer Hide answer
val request = Request(url)
.apply { method = "POST" }
.also { println("prepared $it") }apply configures via this; also runs a side effect via it. Both return the object, so the chain ends with the request.
Back to the lesson, let, run, apply, also, with, or on to the next one: operator overloading.
Comments