Kotlin Scope Functions: let, apply, run, with, and also : With Differences

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hi, this is Sriyank Siddhartha and welcome to another video on Kotlin Fundamentals. Well it is generally seen that developers face a lot of difficulty while dealing with the Scope Functions. So in this video, we will explore what are scope functions, what are the types of different scope functions, what are the differences between those scope functions. Most importantly, when to use them, where to use them and how to use them in your application. And in the end, I will summarize the video in the simplest possible way which will add more sense to your understanding. So stick to this video till the end. Let’s get started. Well, there are 5 types of Scope functions. They are, WITH, LET, RUN, APPLY, and ALSO. Before we explore them, let me show you a gist of how these functions add value to our programs. Suppose this is a class Person... with Two properties... Name and Age. .. right? So, in general, we would instantiate this class object as... Create a Person object And assign values to it... Like this... So no doubt till now.. But let's see the same code using Scope Function. So here.. we create the object. and on that Object we call the APPLY function. Well, APPLY is a scope function which is Basically a higher order function. So in the lambda expression attached to it we will write.. name equal to Sriyank Siddhartha AND Age equal to 26. So in the ordinary code, we have some code repitition. Right..? But here using Scope function, our code is more concise and more readable indeed. Just use the apply function and initialise the properties without using the object name. So in short, the SCOPE FUNCTIONS make your code clear, CONCISE and mode readable. Fine? Now, coming back to our discussion from where we left. So now we know that, by using these functions you can make your program more concise and readable. Let’s explore these functions one by one, in a step by step process. Now these 5 functions are closely related to each other. They are all quite similar in nature and quite often programmers get confused when to use what? So it is very important to understand the differences between them. So how do we differentiate between the scope functions. Well, there are two main differences between each scope function. The first one is the way to refer to the context object. And this is done using either 'this' keyword or by using the 'it' keyword. I hope you are aware of these two keywords. The second one is the RETURN value of the function. These functions either return the context object or the lambda result. Fine? Well, don't worry we will discuss them, what are they .... in our demo. For now don't worry about it. So for WITH function, the return type is the lambda result. and the context object is .... 'this' which refers to the object itself. To understand things better, let us explore a simple and sweet demo of WITH function. DEMO WithFunction.kt So here I have defined a very simple class of Person. With two properties, name and age. Well, I have given default values to these properties. This is not the appropriate way to assign values right here but for the sake of simplicity I have done it. Fine? Next, in the main function. I have initialised the class Person and I am printing the properties of the person object. No doubt till now. But here if you notice, I am repeating the same person object again and again. Imagine if we have 20 such properties and 10 functions that belong to class Person. In such case, there would be abundance of code repeatition. So let's see how to avoid it using WITH function. So I will use with and pass the person object as parameter. And attached to this method is the lambda expression. and you can access this person object using this keyword. For example, you can use print and then this.name. Like this. Similarly, you can print the age. Perfect. So I hope now you understand what it means when we say we can access the context object by using 'this' keyword. Great. Also, you need not explicitly use this keyword within the lambda expression. You can remove them. Don't worry the code will still work. And now you can delete these two lines. You can run the program and check the output remains the same. Great isn't it. Now let us come to the second Property. The return value is the lambda result. So what does it mean? Well, this WITH function Basically returns a result. And that result is the last statement of the lambda expression. For example, at the end if you write 'age + 5', then this value will be returned. That means, Here you can define a variable of the type Int. So this age + 5 will be returned and stored in this variable. And then you can use the value in your program... as per your wish. Now, if you add a String at the end. ... over here.. For example, if you write "He is a freak who loves to teach in his own crazy way" Then now this string will be returned from this function. So this age + 5 will do nothing. Instead of this value, this string will be returned. In short, whatever data is present at the end of the lambda expression will be returned. So instead of Int, it would be String now. And we can change the variable to ... let's say... bio And accordingly, you need to update your program. And the term context object refers to the person Object on which we are performing the operation. Fine? So after WITH function, let's check out the APPLY function. Well, the apply function returns the context object itself. Please note this. and we refer to the context object using 'this' keyword... similar to what we say earlier. So let's see how to use this function. Here we have the class Person with two properties name and age. And now in our program, after we create the person object. Suppose we want to initialise the object properties, then what we usually do? We just initialise them using the object name ... right? But again it leads to code redundancy. So kotlin provides a solution to it. It provides you with the ....APPLY function. So instead of these two statements We can use .apply over here. and within its lambda expression, we can use and So this clearly shows, the property 1. i.e. you can refer to the person object by using this keyword. And of course, within the lambda using this keyword is optional. So if you remove them... your code will work fine. Now what about the second property. Well, the apply function returns the context object itself. i.e. this whole expression will return the person object we are creating. So here on the left, we can use val person equal to... the apply function. fine? If this statement confuses you. then you can split it into two statements. Like this. First create the object and then apply values to it. Nice and simple. But generally we dont use it this way in two statements. We do it one liner. Fine? Now, you can then use the with function ofcouse to print the values. Let us run the program. Perfect. So this is how we use the APPLY function along with the WITH function. Quite simple isn't it. Moving ahead, let's check out the ALSO function. Well, this function returns the context object. And you can refer to the object by using 'it' identifier. So let's see how to use this function. Well, this 'also' function is generally used where we want to perform some additional operation on a particular object after we initialise it. Let me show you an example. Suppose we create an object 'numbersList' with initially 3 integer values...i.e. 1 2 and 3 And then we write some other code here.. And then later, we decide to perform some operations on this numbersList which we have defined here. The operation could be anything, such as print the numbers Add a new number to the list Print the updated list Remove a number And then again print the updated list Then in such situation, we can use the ALSO function. So what we can do is, use numbersList.also function and within the lambda expression Just cut all the code and paste them right here. And as per the Property 1, we can refer to the context object by using 'it' identifier. i.e. you can refer to this numbersList just by using 'it'... like this And so here as well, change it to 'it' Great. Now, if you check the property 2, it says that, the returned object is the context object itself. So this whole function, will return the same numbersList which we have defined here [point to code at top] So if you put Then these two variables will point to exactly same LIST object. let me show you the proof. Let's write print statements for that. Run the program. So these are the print statements from the ALSO function. And at the bottom, you can see, both variables are pointing to the same object. How cool is that? So I guess things are now clear. Let us now take another example where we can use the ALSO function. In this program, where we explored the APPLY function. Here at the top we have initialised the object right... then we have some code... And later suppose you want to modify or perform some operation on the person object which we have created here... then what you can do is.. At the bottom, just use person.also And then modify the name, and you can print and check the new name as well. And of course this whole function will return an object reference which will point to the same person object. But generally, while using ALSO function, we don't keep the reference. So let's remove it. Perfect. So I hope you understand clearly the use case of ALSO function. Moving forward, we have the LET function. Well, let function returns the lambda result. and you can refer to the context object by using 'it' identifier. Let's understand it better in a program. Now, the LET function has a lot of application. But I am going to show you the most important usage of this function. Generally, we use the LET function to avoid NULL pointer exception. Which is a nightmare for most developers across the world. Let's see how. Suppose we have a nullable String variable... name. with the value initialised to null. And we want to perform some operations on it. such as printing the reversed String value OR printing the capitalized string value Or it could be anything such as printing the length of the name String. And here I am using Not-Null Assertion operator to assert that my value is not null. Right. And in case the value is found be null, then this statement will throw NullPointerException. Let us run the program. Here we go, we got NullPointerException. So using let function, you can easily avoid such terrible mistake. All you have to do is, use the name object and call the let function on it. And then cut the code, and paste them within the lambda expression. BUT if you run the program right, it will still throw NullPointerException at this statement. So along with let, you need to use the Safe call operator. which is represented by ? followed by a dot. So after name, lets put ? followed by dot. So this statement Basically means that, execute this code only if the name object is not NULL. Now, once you have taken precaution, you can remove these non null assertion operator. If you run the program now, we get no output because since the name is null, therefore this code was not executed. Hence, we are safe from NullPointerException. Now, let's take a look at the property of LET function. Well, you need to refer to the context object using 'it' identifier. So let's replace 'name' by 'it' everywhere. and the second property says that, the return value is actually the lambda result. Which means whatever value we keep at the end of the lambda expression will be returned. So if we keep it.length at the end, and use a variable length over here. Then the length of the String will be returned and stored in this variable. Fine? And then you can print the value in your program. Like this. Now, let us test our code. For that, let's change this null to some valid String value. and run the program. Here we go, this is the reversed string. this is the capitalised string. and this is the length of the String. Pretty awesome. Now, again there are more use cases of LET function. But trust me usually we use the LET function, for avoiding NullPointerException. So yes that's all for the LET function. It's time to go ahead and explore our last Scope Function... i.e. the RUN function. Well, the run function returns the lambda result and you can refer to the context object by using 'this' keyword. Now, the RUN function is actually the combination on the WITH function and the LET function. Now Why I am saying this? For that, let's see the code in action. If you remember, we explored this code while exploring with function. Here we have the class Person. We created the person object. And Performed some operation using the with function. Right? the code is quite clear. Now, if we make this Person object as NULLABLE. by using a question mark over here. And assign a NULL value to it Then we must find a way out to prevent NULL pointer exception for this piece of code. Right? The best possible solution is to use the RUN function. So using Run function, you can perform what this code was earlier performing. And along with it, you can also avoid the NULL POINTER Exception without writing any extra code. So that is why we say, RUN function is the combination of WITH function and LET function. To implement the run function. just use and within lambda expression, put this code. Like this. And just like LET function, just use a Safe call operator over here. And that is it... you are done. POINTER And similar to with function, like we can return a lambda result over here... the RUN function as well, returns the lambda result. So here as well, we can use val bio So this string will be returned and stored within this variable. And now we can remove this entire code. Perfect. So once again, this code will only be executed if this person object is not null. Thus preventing the NullPointerEception. Perfect. You can now, use a valid Objector creator here and test the output yourself. So yes that's all for RUN function. So we have come up a long way to understand scope functions in this video. And as a beginner, if you are feeling jumbled or confused about when to use what... then i don't blame you for that. Using scope functions at right place is bit tricky. So let's summarise this video and give you a big picture of what we have learnt so far. You can use with function, if you want to operate on a non-null object. You can use let function, if you want to just execute lambda expression on a nullable object and avoid NullPointerEception Next, use RUn function, If you want to operate on a nullable object, execute lambda expression and avoid NullPointerEception Moving on, you can use APPLY function, If you want to initialise or configure an object And finally, you can use ALSO function If you want to do some additional object configuration or operations So in future, whenever you feel confused about when to use what.... just revisit this part of the video. Things will automatically get sorted. So I hope you had a great time learning concepts in this video. This is Sriyank Siddhartha signing off. Thanks for watching and have a nice day.
Info
Channel: Smartherd
Views: 26,838
Rating: 4.9266896 out of 5
Keywords: smartherd, kotlin, scope functions tutorial, scope functions, kotlin scope functions, let, with, apply, run, also, lambda expression, higher order functions, this, it, android, functions, kotlin tutorials, lambda
Id: MHxGv4K6BsM
Channel Id: undefined
Length: 26min 55sec (1615 seconds)
Published: Mon Aug 31 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.