Kotlin Scope Functions

📓 From Kotlin's docs on scope functions:

The Kotlin standard library contains several functions whose sole purpose is to execute a block of code within the context of an object. When you call such a function on an object with a lambda expression provided, it forms a temporary scope. In this scope, you can access the object without its name. Such functions are called scope functions. There are five of them: let, run, with, apply, and also.

Scope FunctionContext Object ReferenceReturn ValueIs Extension Function?
letitlambda result
runthislambda result
withthislambda result
applythisthis
alsoitit

let

.let is fantastic for replacing an object in a call chain.

listOf("Tom", "Dick", "Harry")
  .let(::println)

// 👆 prints: [Tom, Dick, Harry]

run

listOf("Tom", "Dick", "Harry")
  .run { size }

// 👆 results in: 3

with

with(listOf("Tom", "Dick", "Harry")) {
  println("The last element is ${last()}")
  println("There are $size elements")
}

// 👆 prints:
// The last element is Harry
// There are 3 elements

apply

.apply is wonderful for configuring objects, especially those without builders.

mustableListOf()
  .apply { add("Tom") }
  .apply { add("Dick") }
  .apply { add("Harry") }

// 👆 results in: [Tom, Dick, Harry]

also

.also is great for intercepting a call chain and adding some action. I use it extensively to add logging, especially before returning from a method.

mustableListOf("Tom", "Dick")
  .also(::println)
  .add("Harry")
  .also(::println)

// 👆 prints:
// [Tom, Dick]
// [Tom, Dick, Harry]