34

Kotlin let (and other scoped functions)

 4 years ago
source link: https://www.rockandnull.com/kotlin-let/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Article Kotlin

Kotlin let (and other scoped functions)

Bevan Steele

15 Feb 2020 • 2 min read
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)
12345
fun getRandomInt(): Int {
    return Random.nextInt(100).also {
        writeToLog("getRandomInt() generated value $it")
    }
}
12345

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")
}
123456
val numbers = mutableListOf("one", "two", "three")
with(numbers) {
    val firstItem = first()
    val lastItem = last()        
    println("First item: $firstItem, last item: $lastItem")
}
123456

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.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK