kotlinbeginner
Scope Functions — let, run, apply, also, with
Master Kotlin scope functions: when to use let, run, apply, also, and with for concise code.
kotlinPress ⌘/Ctrl + Shift + C to copy
data class Config(
var host: String = "localhost",
var port: Int = 8080,
var debug: Boolean = false,
var tags: MutableList<String> = mutableListOf()
)
fun main() {
// let — transform nullable, return result
val name: String? = "Alice"
val greeting = name?.let { "Hello, $it!" } ?: "Hello, stranger!"
println(greeting) // Hello, Alice!
// let — scoped variable
val numbers = listOf(1, 2, 3, 4, 5)
numbers.filter { it > 2 }
.let { filtered ->
println("Filtered: $filtered, Sum: ${filtered.sum()}")
}
// apply — configure object, return object itself
val config = Config().apply {
host = "prod.example.com"
port = 443
debug = false
tags.add("production")
}
println(config)
// also — side effects, return object
val user = createUser("Bob")
.also { println("Created user: ${it.first}") }
.also { logUser(it) }
println("User: $user")
// run — block on object, return result
val isSecure = config.run {
port == 443 && !debug
}
println("Secure: $isSecure") // true
// run — without receiver (scoped computation)
val serverUrl = run {
val protocol = if (config.port == 443) "https" else "http"
"$protocol://${config.host}:${config.port}"
}
println(serverUrl)
// with — call methods on object
val info = with(config) {
"Server at $host:$port (debug=$debug)"
}
println(info)
// Chaining pattern
val result = StringBuilder()
.apply { append("Hello") }
.apply { append(", ") }
.apply { append("World!") }
.toString()
println(result)
// Decision guide:
// ┌──────────┬──────────────┬───────────────┐
// │ Function │ Object ref │ Return value │
// ├──────────┼──────────────┼───────────────┤
// │ let │ it │ Lambda result │
// │ run │ this │ Lambda result │
// │ with │ this │ Lambda result │
// │ apply │ this │ Object itself │
// │ also │ it │ Object itself │
// └──────────┴──────────────┴───────────────┘
}
fun createUser(name: String) = Pair(name, "${name.lowercase()}@test.com")
fun logUser(user: Pair<String, String>) { /* log */ }Use Cases
- Object initialization and configuration
- Null-safe transformations with let
- Logging and debugging side effects with also
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
kotlinbeginner
Destructuring Declarations
Destructure objects into variables: data classes, maps, pairs, and custom componentN operators.
Best for: Clean variable extraction from complex objects
#kotlin#destructuring
kotlinbeginner
Null Safety — Elvis, Safe Call, and let
Master Kotlin null safety: safe calls, Elvis operator, let/also scoping, and smart casts.
Best for: Safe navigation through nullable chains
#kotlin#null-safety
kotlinbeginner
Data Classes — Copy, Destructure, and Equals
Use data classes for immutable models: auto-generated equals, hashCode, copy, and destructuring.
Best for: Immutable domain models and DTOs
#kotlin#data-class
kotlinbeginner
Collections — map, filter, groupBy, and More
Master Kotlin collections: functional transformations, aggregations, grouping, and partition operations.
Best for: Data processing and transformation pipelines
#kotlin#collections