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 |