Kotlin let (and other scoped functions)
Kotlin has many unique language features for someone coming from Java. One of the small but loved is the scoped functions.
If you read some Kotlin code before you probably already seen them. You may even use them without knowing exactly the differences between them.
All of them serve the same purpose: create a section of code where the code executed refers to an object. These are great because in Java you would have to declare a temporary variable to modify an object before returning it.
I am talking about let
, run
, with
, apply
and also
. The differences between them:
- What is returned
- How the object is referenced inside the scoped function
To make it easier here is a table with all the combinations:
Scoped function | Returns | Object reference |
---|---|---|
let | lamda result | it |
run | lambda result | this |
with | lambda result | this |
apply | object | this |
also | object | it |
A more practical way to group these methods (for hopefully remember using them when needed) is by use-case.
Since apply
and also
return the object itself, they are useful for object configuration and building.
val adam = Person("Adam").apply {
age = 20
city = "London"
}
println(adam)
fun getRandomInt(): Int {
return Random.nextInt(100).also {
writeToLog("getRandomInt() generated value $it")
}
}
For having additional effects or grouping function calls on an object use let
, run
, with
.
val numbers = mutableListOf("one", "two", "three", "four", "five")
numbers.map { it.length }.filter { it > 3 }.let {
println(it)
}
val service = MultiportService("https://example.kotlinlang.org", 80)
val result = service.run {
port = 8080
query(prepareRequest() + " to port $port")
}
val numbers = mutableListOf("one", "two", "three")
with(numbers) {
val firstItem = first()
val lastItem = last()
println("First item: $firstItem, last item: $lastItem")
}
But what about this
and it
? The practical difference is that when passing the object as an argument (i.e. with it
) you are allowed to give a custom name for the object inside the context function.
Like with every language "trick", you should be careful not to overdo it. Otherwise, a feature that was designed to write more readable and concise code will have the opposite effects (e.g. if you start nesting these functions too much you might be confused where it
or this
refers to).
For more details on the subject, read the excellent official documentation on the feature.