Table of Contents
I categorized scope functions, let, with, also, apply, run in Kotlin.
Classification
Scope functions can be classified with 3 aspects.
| Identifier | Extension Function | The Object represented as | Return Value |
|---|---|---|---|
| also | Yes | it | The Object |
| let | Result | ||
| apply | this | The Object | |
| run | Result | ||
| with | No |
Is Extension Function or not
This difference is affect to null handling. When it is an extension function, we can use .? before calling. with is not an extension function, it can’t be called as nullable?.with.
As you can see in above table, with is similar to run for non-null value. The following code explains.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
lateinit var message: String // change message message.run { toUpperCase() toLowerCase() } with(message) { toUpperCase() toLowerCase() } |
But for nullable value.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
lateinit var message: String? // change message message?.run { toUpperCase() toLowerCase() } with(message) { this?.toUpperCase() this?.toLowerCase() } |
Thus, extension function can easily handle nullable type, using .?.
The object is represented as
it or this represents the object in scope functions.
In also, let, it can be used, and we can call the class with this if it’s in a class, and call other functions in the class. We can rename the object from it to other. The disadvantage is that we have to write it every time we call the object’s method and property. From another aspect, it is easy to understand whose method is called because it appears every time.
In with, apply and run, the object is represented as this. So, the object’s method and property is called directly. If the scope function is used in a class, the class’s method and property also can be called directly. In other words, it is not so easy to distinguish the object’s method and property from class’s method and property at a glance.
| Identifier | Advantage | Disadvantage |
|---|---|---|
| it |
|
|
| this |
|
|
Return Value
スコープ関数は、自分自身の値が返り値になるのか、ブロックの実行結果の値が返り値になるのかでわかれます。
This effects when we build method chain.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
1. apply { plus(1) } . apply { plus(1) } . apply { plus(1) } . apply { println(this) } // => 1 1. run { plus(1) } . run { plus(1) } . run { plus(1) } . run { println(this) } // => 4 |


