Labs ICT
โญ Pro Login

Scope Functions

Scope functions are small helpers that create a temporary scope for an object. They let you write cleaner, more focused code by avoiding repetitive variable names. Kotlin gives you five: let, apply, with, also, and run.

let โ€” transform and avoid nulls

let executes a block on a non-null object and returns the last expression. Great for null checks and chaining.


fun main() {
  val name: String? = "Alice"

  name?.let {
    println("Hello, $it!")
  }

  val length = name?.let { it.length } ?: 0
  println(length)
}
    

Inside let, the object is available as it (or you can name it). Combined with safe call ?., it only runs when the value isn't null.

Try it Yourself โ†’

apply โ€” configure objects

apply runs a block on an object and returns that same object. Perfect for initializing properties.


class Person(var name: String, var age: Int)

fun main() {
  val person = Person("Unknown", 0).apply {
    name = "Bob"
    age = 30
  }
  println("${person.name} is ${person.age}")
}
    

Inside apply, you're in the object's context โ€” no need to repeat the variable name. The object itself is the return value.

Try it Yourself โ†’

with, also, and run

with is like apply but returns the last expression. also is like let but returns the original object. run combines let and with.


class Guitar(var brand: String, var strings: Int)

fun main() {
  val guitar = Guitar("Fender", 6)

  val description = with(guitar) {
    "Brand: $brand, Strings: $strings"
  }
  println(description)

  guitar.also {
    it.strings = 7
  }.also {
    println("Now has ${it.strings} strings")
  }

  val result = guitar.run {
    strings = 12
    "Modified: $brand with $strings strings"
  }
  println(result)
}
    

Use with to run operations without returning the object. Use also for side effects (like logging). Use run when you want to both transform and return something new.

Try it Yourself โ†’

Quick reference

  • let โ€” context: it, returns: last expression
  • apply โ€” context: this, returns: the object
  • with โ€” context: this, returns: last expression
  • also โ€” context: it, returns: the object
  • run โ€” context: this, returns: last expression

Not sure which to pick? Start with let for null checks, apply for configuring objects, and also for side effects. The rest will click with practice.

๐Ÿงช Quick Quiz

Which scope function returns the context object itself?