/compare/kotlin/let-vs-apply-vs-also-vs-run
Kotlin let vs apply vs also vs run vs with: scope functions compared
The commands on this page have not been executed by our verification runner yet.updated
- tool
- Kotlin
- compares
- let / also vs apply / run / with
Kotlin's five scope functions all run a block on an object; they differ in how the block refers to the object (it or this) and what they return (the object itself or the block's result). let (it, returns the result) is for null checks and transforming a value; apply (this, returns the object) configures an object; also (it, returns the object) adds side effects such as logging; run (this, returns the result) computes a value from an object; with(obj) is run called as a normal function.
The table to remember
| Function | Object inside the block | Returns | Typical use |
|---|---|---|---|
| let | it | Block result | x?.let { ... } null checks, mapping a value |
| also | it | The object | Side effects: logging, validation, adding to a list |
| apply | this | The object | Configuring an object (builder style) |
| run | this | Block result | Computing a result from an object; also run { } without receiver |
| with(obj) | this | Block result | Calling several members of an object; not an extension |
Examples
data class User(var name: String, var email: String? = null)
// let: run only when non-null, return the result
val length = readlnOrNull()?.let { it.trim().length } ?: 0
// apply: configure and return the same object
val user = User("ada").apply {
email = "ada@example.com"
}
// also: side effect, the object passes through unchanged
val saved = user.also { println("saving ${it.name}") }
// run: compute a value with the object as this
val label = user.run { "$name <${email ?: "no email"}>" }
// with: same as run, but the object is an argument
val summary = with(user) { "$name has ${if (email == null) "no" else "an"} email" }How to choose
- Need the object back?
apply(configure it) oralso(do something with it). - Need a different value back?
let(withit) orrun/with(withthis). - Nullable receiver? Use the extension forms with
?.:x?.let,x?.run,x?.apply.with(x)has no safe-call form. - Prefer
it(let, also) when the block also uses the outerthis, to avoid confusing the two receivers.
Sources
Related pages
compare · kotlinKotlin val vs var: read-only vs mutable variablesIn Kotlin, val declares a read-only reference assigned once and var a mutable one. A val object can still change inside. When to use each one, and const val.errors · kotlinKotlin: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?Kotlin rejects a plain dot call on a nullable type like String?. Use ?. for a null result, ?: for a default, or check for null first so the value is smart-cast.glossary · kotlinWhat is a data class in Kotlin?A Kotlin data class holds values and gets equals, hashCode, toString, copy and componentN generated from its primary constructor. Rules, example, when to use.