Kotlin Scope Functions Cheatsheet
Scope Functions
When called on object it forms a temporary scope.
| Function | Object reference | Return value |
|---|---|---|
| let | it | Lambda result |
| run | this | Lambda result |
| with | this | Lambda result |
| apply | this | Context object |
| also | it | Context object |
| takeIf | it | Context object or null |
| takeUnless | it | Context object or null |
let
Lets you not have to assign the result
// Old
val numbers = mutableListOf("one", "two", "three", "four", "five")
val resultList = numbers.map { it.length }.filter { it > 3 }
println(resultList)
// New
val numbers = mutableListOf("one", "two", "three", "four", "five")
numbers.map { it.length }.filter { it > 3 }.let {
println(it)
// and more function calls if needed
}
Execute block containing non-null values
val str: String? = "Hello"
//processNonNullString(str) // compilation error: str can be null
val length = str?.let {
println("let() called on $it")
processNonNullString(it) // OK: 'it' is not null inside '?.let { }'
it.length
}
Provide a name for the object with limited scope to make code easier to read
val numbers = listOf("one", "two", "three", "four")
val modifiedFirstItem = numbers.first().let { firstItem ->
println("The first item of the list is '$firstItem'")
if (firstItem.length >= 5) firstItem else "!" + firstItem + "!"
}.uppercase()
println("First item after modifications: '$modifiedFirstItem'")
with
Similar to let, context is this
“with this object, do the following.”
val numbers = mutableListOf("one", "two", "three")
val firstAndLast = with(numbers) {
println(this.first())
"The first element is ${first()}," +
" the last element is ${last()}"
}
println(firstAndLast)
run
Does the same as with but as an extension function
“run the code block and compute the result.”
val service = MultiportService("https://example.kotlinlang.org", 80)
val result = service.run {
port = 8080
query(prepareRequest() + " to port $port")
}
// the same code written with let() function:
val letResult = service.let {
it.port = 8080
it.query(it.prepareRequest() + " to port ${it.port}")
}
apply
Returns context object itself, often used for object configuration.
“apply the following assignments to the object.”
val bjj = MartialArt("BJJ").apply {
type = "grappling"
this.origin = "Brazil"
}
println(bjj)
also
“and also do the following with the object.”
val numbers = mutableListOf("one", "two", "three")
numbers
.also { println("The list elements before adding new one: $it") }
.add("four")
takeIf
Returns the object if it satisfies the given predicate, otherwise it returns
null. Essentially a filter for a single object
val evenOrNull: Long? = value.takeIf { it % 2 == 0}
takeUnless
Returns the null if it satisfies the given predicate, otherwise it returns
the object. Opposite of takeIf
val oddOrNull: Long? = value.takeIf { it % 2 == 0}