Kotlin Let vs Run vs With vs Apply vs Also: Key Differences
let and run are scope functions that use it and this respectively as context objects, with let returning the lambda result and run returning the lambda result too. with is a non-extension function using this as context and returns the lambda result, while apply and also return the original object; apply uses this and also uses it as context. Each serves different readability and chaining purposes.Quick Comparison
Here is a quick table summarizing the key differences between let, run, with, apply, and also in Kotlin.
| Function | Context Object | Return Value | Extension Function | Typical Use Case |
|---|---|---|---|---|
| let | it | Lambda result | Yes | Null checks, chaining transformations |
| run | this | Lambda result | Yes | Execute block with object context, compute result |
| with | this | Lambda result | No | Operate on object without extension, compute result |
| apply | this | Original object | Yes | Initialize or configure object |
| also | it | Original object | Yes | Perform additional actions like logging |
Key Differences
let uses it as the context object inside its lambda and returns the lambda's result. It is often used for null safety checks and chaining transformations because it allows you to work with the object as it.
run uses this as the context object and also returns the lambda result. It is useful when you want to execute a block of code with the object as the receiver and get a computed result.
with is a regular function (not an extension) that takes the object as an argument and uses this inside the lambda, returning the lambda result. It is handy when you want to operate on an object without calling it as an extension.
apply uses this as the context object and returns the original object, making it perfect for initializing or configuring objects in a fluent style.
also uses it as the context object and returns the original object, which is great for performing side actions like logging or debugging without altering the object.
Code Comparison
val name: String? = "Kotlin" // Using let for null check and transformation val length = name?.let { println("Name is $it") it.length } println("Length: $length")
Run Equivalent
val name: String? = "Kotlin" // Using run to execute block and return result val length = name?.run { println("Name is $this") length } println("Length: $length")
When to Use Which
Choose let when you want to work with the object as it, especially for null checks or chaining transformations.
Choose run when you want to execute a block with this as context and return a computed result.
Choose with when you want to operate on an object without extension syntax and get a result.
Choose apply when you want to configure or initialize an object and return it for chaining.
Choose also when you want to perform side effects like logging or debugging without changing the object.
Key Takeaways
let and also use it as context; run, with, and apply use this.let, run, and with return the lambda result; apply and also return the original object.apply is best for object configuration; also is best for side effects like logging.with is a non-extension function useful for operating on objects without extension syntax.let for null safety and chaining, run for executing blocks with this, and also for additional actions.