Scope Function in Kotlin

What is Scope Function?

Scope Function execute a block of code within context of object.That is if you perform this function on an object inside an lambda expresssion then the scope inside the expression will be executed that is called Scope Function

Types Of Scope Function

let → we use this often when we want to execute any operation on not null values by using safe call operator ?.

Always let refer the context of object by using it and return lambda result as an return value

We can pass any local variable inside the scope for the replacement of it so its easy readable

Sample Program on let:

var name:String ?=null
val result = name?.let { value ->
value.length
}
print("result--"+result)

In the above example it wont execute the let function if the name value is null

var name:String ?= "Pandiyan"
val result = name?.let { value ->
value.length
}
println("result--"+result)
output:
result--8

In the above example output is 8

run → Used when the object lambda contains both initialization and the computation of the return value. Using run we can perform null safety calls as well as other computations.

class Company() {
lateinit var name: String
lateinit var objective: String
lateinit var founder: String
}

fun main(args: Array<String>) {
println("Company Name : ")
var company: Company? = null
// body only executes if
// company is non-null
company?.run {
print(name)
}
print("Company Name : ")
// re-initialize company
company = Company().apply {
name = "GeeksforGeeks"
founder = "Sandeep Jain"
objective = "A computer science portal for Geeks"
}
// body executes as
// 'company' is non-null
company?.run {
print(name)
}
}

with → It takes context of object as an argument and perform operation on it

It refer the context of object by using this and return lambda result as an return value

We can perform not null operation here but we have to give not null assertion on each line which doesn't look nice

class Company() {
lateinit var name: String
lateinit var objective: String
lateinit var founder: String
}

val gfg = Company().apply {
name = "GeeksforGeeks"
objective = "A computer science portal for Geeks"
founder = "Sandeep Jain"
}

// with function
with
(gfg) {
// similar to println( "${this.name}" )
println
(" $name ")
}

apply → As the name implies “apply on the object” it refer the context of object by using this and return the context object itself its is mainly used for initialize the members.

class Company() {
lateinit var name: String
lateinit var objective: String
lateinit var founder: String
}

fun main() {
Company().apply {
// same as founder = “Sandeep Jain”
this.founder = "Sandeep Jain"
name = "GeeksforGeeks"
objective = "A computer science portal for Geeks"
}
}

also → It will be used when we want to do any additional operation after initialization of member and it refer the context of object by using it and return context object itself

fun main() {
// initialized
val list = mutableListOf<Int>(1, 2, 3)

// later if we want to perform
// multiple operations on this list
list.also {
it
.add(4)
it.remove(2)
// more operations if needed
}
println(list)
}