Created
June 30, 2023 10:31
-
-
Save senamit2708/3ed496f970d770f8a113f18c5cb862b3 to your computer and use it in GitHub Desktop.
scope function learning
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| there are five types of scope functions: makes your code clear, concise and more readable | |
| with | |
| let | |
| run | |
| apply | |
| also | |
| two main difference between them | |
| 1. the way to refer the context object -> either this or it | |
| 2. the return value either contextObject or the lambda result | |
| with: | |
| context-> this | |
| return -> lambda | |
| */ | |
| //start[learning with] | |
| class Person() { | |
| var name: String = "amit" | |
| var age: Int = 23 | |
| } | |
| /*fun main(){ | |
| val person = Person() | |
| // println("name is ${person.name}") | |
| // println("age is${person.age}") | |
| //simple example | |
| with(person){ | |
| println(this.name)//this keyword is also not required because bydefault its taking this | |
| println(this.age) | |
| } | |
| //here return is lambda and context is this | |
| val ageAfterfiveYear: Int = with(person){ | |
| println(this.name) | |
| println(this.age) | |
| age+5 | |
| } | |
| println("age after 5 years is $ageAfterfiveYear") | |
| }*/ | |
| //End [learning with] | |
| //Start[apply] | |
| /*class Person(){ | |
| var name: String = "" | |
| var age: Int = 23 | |
| } | |
| fun main(){ | |
| //used to assign the value to the variables of the class | |
| val person = Person().apply { | |
| this.name = "amit sen" | |
| this.age = 30 | |
| } | |
| with(person){ | |
| println(name) | |
| println(age) | |
| } | |
| }*/ | |
| //End[apply] | |
| //Start[also] | |
| /*fun main(){ | |
| val numberList = mutableListOf<Int>(1,3,4) | |
| val duplicateNumber = numberList.also { | |
| it.add(5) | |
| it.remove(3) | |
| println("the list elements are $it") | |
| } | |
| println("origianl numberlist $numberList") | |
| println("duplicate numberlist $duplicateNumber") | |
| } | |
| the list elements are [1, 4, 5] | |
| origianl numberlist [1, 4, 5] | |
| duplicate numberlist [1, 4, 5]*/ | |
| //second example | |
| /*class Person(){ | |
| var name: String = "" | |
| var age: Int = 23 | |
| } | |
| fun main(){ | |
| //used to assign the value to the variables of the class | |
| val person = Person().apply { | |
| this.name = "amit sen" | |
| this.age = 30 | |
| } | |
| with(person){ | |
| println(name) | |
| println(age) | |
| } | |
| //so here it is used if u want to do some varaible data changes use also function | |
| person.also { | |
| it.name = "amit new name" | |
| println("name is ${it.name}") | |
| } | |
| println("name is ${person.name}")//amit new name | |
| }*/ | |
| //End[also] | |
| //Start[let] | |
| //used for avoiding nullpoint exceptions | |
| /*fun main(){ | |
| val name:String? = "amit" | |
| val nameLength = name?.let { | |
| println("name reversed ${it.reversed()}") | |
| println("captalized ${it.capitalize()}") | |
| it.length | |
| } | |
| println("length of name $nameLength") | |
| }*/ | |
| //End[let] | |
| //Start[Run] | |
| //this function is a combination of with and let scope function | |
| /*class Person(){ | |
| var name: String = "amit" | |
| var age: Int = 23 | |
| } | |
| fun main(){ | |
| val person = Person() | |
| //so here with is used alsong with let | |
| person?.run { | |
| println(name) | |
| println(age) | |
| age+5 | |
| } | |
| }*/ | |
| //with -> lambda,this | |
| //let-> lambda, it | |
| //run-> lambda, this | |
| //apply-> context obj, this | |
| //also-> context Obj, it | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //SCOPE Function | |
| /*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. | |
| Basically, these functions all perform the same action: execute a block of code on an object. | |
| What's different is how this object becomes available inside the block and what is the result of the whole expression. | |
| */ | |
| /* | |
| two main difference between them | |
| 1. the way to refer the context object -> either this or it | |
| 2. the return value either contextObject or the lambda result | |
| //with -> lambda,this | |
| //let-> lambda, it | |
| //run-> lambda, this | |
| //apply-> context obj, this | |
| //also-> context Obj, it | |
| -------where to execute which scope function ------- | |
| Executing a lambda on non-null objects: let | |
| Introducing an expression as a variable in local scope: let | |
| Object configuration: apply | |
| Object configuration and computing the result: run | |
| Running statements where an expression is required: non-extension run | |
| Additional effects: also | |
| Grouping function calls on an object: with | |
| ------------------------------------------------- | |
| this -> lambda receiver | |
| it -> lambda argument | |
| ---------- | |
| let, run, and with return the lambda result. So you can use them when assigning the result to a variable, chaining operations on the result, and so on. | |
| val numbers = mutableListOf("one", "two", "three") | |
| val countEndsWithE = numbers.run { | |
| add("four") | |
| add("five") | |
| count { it.endsWith("e") } | |
| } | |
| println("There are $countEndsWithE elements that end with e.") | |
| ------------- | |
| The return value of apply and also is the context object itself. Hence, | |
| they can be included into call chains as side steps: you can continue chaining function calls on the same object, one after another. | |
| val numberList = mutableListOf<Double>() | |
| numberList.also { println("Populating the list") } | |
| .apply { | |
| add(2.71) | |
| add(3.14) | |
| add(1.0) | |
| } | |
| .also { println("Sorting the list") } | |
| .sort() | |
| */ | |
| data class Employee(var name: String = "Amit", var age: Int = 32, var address: String = "Bihar") | |
| fun main() { | |
| // letFun() | |
| // runFun() | |
| // withFun() | |
| // withOrRunFun() | |
| // applyFun() | |
| alsoFun() | |
| } | |
| fun letFun() { | |
| val employeeOne = Employee().let { | |
| return@let "Employee name is ${it.name}" | |
| } | |
| println(employeeOne) //Employee name is Amit | |
| //note -> It is not necessary to write “return@let”. This is only done to enhance code readability. In Kotlin, | |
| val employeeTwo = Employee().let { | |
| it.name = "sohan kumar" | |
| it.name | |
| } | |
| println(employeeTwo) //sohan kumar | |
| //note -> if the last statement in a “ let ” block is a non-assignment statement, it is by default a return statement. | |
| val employeeThree = Employee().let { | |
| it.name = "saurav" | |
| } | |
| println(employeeThree) //kotlin.Unit | |
| //note -> if we don’t return anything in the “ let ” block? and also last statement is assignment. | |
| // It is similar to calling a function that has no return value | |
| val name = Employee().name?.let { | |
| "name of employee is $it" | |
| } | |
| println(name)//name of employee is Amit | |
| //null safety ?.let | |
| val numberList = mutableListOf(1, 2, 3, 4, 5) | |
| numberList.filter { it > 3 }.let { | |
| println(it) //[4, 5] | |
| //note -> chain of task | |
| } | |
| } | |
| fun runFun() { | |
| val employeeOne = Employee().run { | |
| name = "Saurav" | |
| age = 43 | |
| return@run "name is $name" | |
| } | |
| println(employeeOne) //name is Saurav | |
| } | |
| fun withFun() { | |
| val employeeOne = with(Employee()) { | |
| return@with "name of employee is $name" | |
| } | |
| println(employeeOne) //name of employee is Amit | |
| } | |
| fun withOrRunFun() { | |
| val employeeOne: Employee? = null | |
| with(employeeOne) { | |
| this?.name = "saurav" | |
| this?.age = 42 | |
| this?.address = "bhopal" | |
| } | |
| employeeOne?.run { | |
| name = "shyam" | |
| age = 12 | |
| address = "professor colony" | |
| } | |
| //note -> when u have to cross check null safety, its good to go with run or let rather than with. | |
| } | |
| fun applyFun() { | |
| val employeeOne: Employee? = null | |
| employeeOne?.apply { | |
| name = "saurav" | |
| age = 33 | |
| address = "patna" | |
| } | |
| //difference between run and apply is that return@apply is not available. | |
| } | |
| fun alsoFun() { | |
| val employee = Employee().also { | |
| it.name = "saurav" | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment