Try 5 scope function in kotlin
Tags: android, kotlin, scope
Published: 2019-11-26 15:00:50

---
title: Try 5 scope function in kotlin
published: true
description: Lot of us already used these function but maybe you wondering why i use these, lets explore the 5 functions.
tags: android, kotlin, Scope
---

##with
When we should use this? **with** function use for call multiple different methods on the same object. Instead we use repetition to call variable or function in that object on every line, we can use *with* function. This function categories as normal function and not extensions function type, and the the last expression contain returns statement as a result. You should aware if this object contain null it will be trigger NPE, because this function never check for nullability. 
You can direct call the function or variable in that object without *it* keyword. *with* function cannot add argument in their block statement because it mimic as argument instead object reference, and when if you not define the return value in the last expression, the result type will be *unit/void* type.

```kotlin
val product = Product()
with(product) {
change -> //this argument will be error or invalid
        productId = 1
        nameOfProduct = "Smartphone"
//You can add at last line with the variable type as the return value.
    }
```

##let
When we should use this? **let** function use for you want to define a variable for specific scope to your code. *let* will invoked as parameter and returns the result of the lambda expression. Specific scope will only cover in your object that contain *let* function. i always use for checking nullability if the current object is null or not. This object never change the out of current object properties, only change in the scope. You should type *it* keyword to obtain the variable and add explicity return value in last statement to become result value or if you not do this it will be *unit* as the type.

```kotlin
val product = Product()
 product.let { 
        it.productId = 1
        it.nameOfProduct = "Smartphone"
//You can add at last line with the variable type as the return value.
    }
```

```kotlin
val product = Product()
 product.let { currentProduct ->
        currentProduct.productId = 1
        currentProduct.nameOfProduct = "Smartphone"
//You can add at last line with the variable type as the return value.
    }
```

##run
When we should use this? **run** function is like combination of *with* and *let*. it have null checking so if the object is null the the block statement will never execute, and same as *with* function that can call multiple different method or variable in the same object. *it* keyword never supported in *run* function, instead use *it* keyword *run* function will use *this* operator. You can add *this* operator explicit or not, for call the variable/method inside that object. 
Passing argument as lambda expression cannot be used in *run* function. Then same as *let* or *with* you must explicit add return value in the last statement to get the result type.

```kotlin
val product = Product()
product.run {
currentProduct -> //this argument will be error or invalid
        productId = 1
        nameOfProduct = "Smartphone"
//You can add at last line with the variable type as the return value.
        
    }
```

```kotlin
val product = Product()
product.run {
        this.productId = 1
        this.nameOfProduct = "Smartphone"
//You can add at last line with the variable type as the return value.
        
    }
```

##also
When we should use this? **also** it will pass the object as parameter with return the same original object type. When you try to change in type in last statement based on the scope the return will be same as original object, so the atribute that you change in the scope will never applied for the current object type. *also* can use passing by argument in lambda expression so you can passing argument on this function as well. These function can use *it* operator, so if there pass argument by lambda expression the *it* operator will work.

```kotlin
val product = Product()
product.also {
        it.nameOfProduct = "Smartphone"
        it.productId = 1
//The return value remain product
    }
```

```kotlin
val product = Product()
product.also { currentProduct ->
        currentProduct.nameOfProduct = "Smartphone"
        currentProduct.productId = 1
//The return value remain product
    }
```

##apply
When we should use this? **apply** its different from other function, that function is like extensions function type. it will run on the object reference  or the receiver into expression and return the same original object type. You should notice about *it* keyword that not allowed in this function, instead use *it*, apply use *this* keyword. *this* keyword as a argument and as a return value. You dont need explicit add this operator to call the variable object just direct call the variable inside that object.

```kotlin
val product = Product()
product.apply {
currentProduct -> //this argument will be error or invalid
        productId = 1
        nameOfProduct = "Lipstik"
    }
```

```kotlin
product.apply {
        this.productId = 1
        this.nameOfProduct = "Lipstik"
    }
```

![kotlin function image](https://thepracticaldev.s3.amazonaws.com/i/v7ok6u2mkgn0ps2lf50i.png)