Kotlin Scope functions :let, run ,also apply, with

Kotlin Scope functions :let, run ,also apply, with

The Kotlin standard library comes with many functions to and the scope functions is one of them. So what exactly is a scope function? There are instances when we need to execute a block of code within a context of an object. These functions can be called on an object by providing a lambda expressions to form a temporary scope where the object can be accessed without its name. The scope functions make your code more concise and readable. Scope functions are quite similar and its important to understand the difference between them. The two most notable features between the scope functions are:

  • Their return value and
  • The way the refer to the context objects

let

This is the most commonly used scope function. The major issue Kotlin developers face is handling null safety issues when working with nullable data types. This is where the let function comes in, to handle null checks. Let's check an example below.

private var character:String = "Dart Vader"
character?.let{
    println(it.length)
}

Here we are making a safe call using ?. operator. The let function will only call when the value of character is not null or empty. Otherwise it will skip. Alternatively we can do it as below.

 Character("Darth Vader", "Death Star").let{
    println(it)
}

also

also is used for doing operations on intermediate results without transforming or modifying the object taking the object as an argument. As per official Kotlin Documentation, when you see also you can read it as:

“and also do the following with the object.”

val characters = mutableListOf("Darth Vader", "Luke Skywalker","Yoda","Chewbacca")
characters.also{
    println("StarWars Characters: $it")
}

apply

This scope function is mainly used to perform object configuration.The returned object will be configuration applied on it. Here is an example

val darthvader = Character("Darth Vader").apply{ 
    height = 202
    birth_year = "41.9BBY"
    gender = "Male"
    skin_color = "white"
}
println(darthvader)

run

run invokes asletwe userun` whenever we want to perform some operation on the object but the result is not the same object itself, but the return type of that operation is something else.

val character = "Darth Vader"
character = run{
    val bio = "Darth Vader is a fictional character in the Star Wars franchise."
}
println(character)
/**Darth Vader is a fictional character in the Star Wars franchise**/

with

with is same as run just with a different signature. It is used to change the instance properties of an object.