Function Literals and Closures in Golang - Part 1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up everybody my name is moss and in this video i'm going to talk to you about function literals and closures in the go programming language i'm going to walk you through several code examples that utilize function literals enclosures if you haven't already go ahead and grab a coffee and let's take a look at some code so in this first example we have a simple go program and inside of this go program we have the main function and then inside of the main function we have defined a function literal so a function literal is simply an anonymous function and an anonymous function is not named we could define it inline inside of another function and this is a very simple function literal all it's doing is printing out to the console the number five and if we were to open up a terminal and run this we should see the number five printed out to the screen which we do okay so this uh function literal is just printing out to the console the number five and it's being called right here on line 12. so if we were to remove this this function this code would not be ran and it gives me an error also indicating that this function literal is evaluated but not used right so in order to use this function literal i have to actually call it after the definition and there i call it on line 12 and it will now run this code when we run the program so that's simple enough now let's take a look at a second example and in this second example we're actually going to assign a function literal to a variable so we can actually assign a function to a variable and in this case we're assigning um a function literal to this variable number printer so number printer is going to be equal to this function literal that prints to the console the variable number and number is defined up here as six so when we define this function literal notice that we're not invoking it like in the previous example immediately after the definition and that's because we're assigning it to a variable that we can then treat as a function because this is being assigned to a function so later on in the program you'll see on line 16 we're actually invoking a number printer as if it's a function because it is it's assigned to a function so we can now invoke it the same way so on line 16 we invoke number printer which is going to run this code on line 13 and it should print out the number six when we run the program so let's go ahead and take a look at the terminal and see if it does so and we get the number six so again this is a simple example but if we wanted to we could remove the assignment here to number printer and remove the invocation and treat it like the last example where we invoked it directly after the declaration and it'll work just the same so if i rerun it and i get the number six just like uh when we had the assignment to number printer so let's move on to another example and in this example we're actually uh defining a separate function outside of main called number printer and then inside of number printer we are defining a a function literal and this function literal is a closure why is it a closure well inside of this function literal we're referencing the number variable and the number variable is not defined within the the uh this function literal it's actually defined in the number printer function okay so it's not defined inside the body of the function literal and because of that we're referencing it a variable that is defined outside of the function body then this it makes this function literal a closure or what's known as a closure now when number printer gets called with a number as input that number is printed out to the screen inside of this function literals body so the function literal is invoked after its declaration here so in the main function you can see here we call number printer with the number seven and then inside the body uh of the function literal we're printing out number seven so let's take a look at the at the command line and see if this prints out correctly and you can see it prints out the number seven okay so again pretty simple not a very complex example in this case so let's go ahead and move on to a slightly more complex example showing some other characteristics of closures so there's an important property of closures that's defined in the definition of closures you'll find it on the the go programming language specification for function literals it says function literals are closures they may refer to variables defined in a surrounding function those variables are then shared between the surrounding function and the function literal and they survive as long as they are accessible and that's really an important point and one that we're going to demonstrate in these functions so if we take a look at the counter function here the counter function returns a function and that function's return uh data type is integer okay this is going to be our function closure and inside of the counter function we define a variable number which is uh integer of integer type and then we have our function closure defined so we return a function that doesn't take any input and returns an integer and that function increments the number variable by one and this will be initialized by default uh to zero so we increment the number variable variable by one and then we return the number variable okay so notice that after this definition we're not actually invoking this function so we're returning this function is returning a function that we can uh invoke anytime that we want now if we go down to the main function we have a variable here defined as first counter and it's assigned to an invocation of counter and what is this returning what is counter returning well it's returning a function okay and now first counter is assigned to that function it's assigned to this function right here this closure okay so when we want to increment the number variable we simply call first counter because it's assigned to this function right here so when we call first counter what we'll get is the number one printed out to the screen now going back to that definition where uh enclosures it says that the variables inside of closures that are shared with the um the outer function in this case the count counter they live as long as they're accessible so this number variable continues to live even after the function exits right so in this case one is printed out to the screen but the second time we call first counter first counter is still referring to the same number variable it's not initializing a new number variable in this case it's referring to the same number variable as it was in this first invocation of of first counter so it's going to increment the same variable and it should print out to the screen the number two and if we want a new number variable initialize we can assign a new variable in this case we're assigning second counter to an invocation of counter which returns a closure it returns this function okay and then we invoke second counter this time when we print this out to the screen the first invocation of a second counter is going to print one because we are now incrementing a new uh initialized number variable okay and then when we invoke second counter again it will be incrementing that same variable and it should print out two to the screen so let's go ahead and open up our console and see if it runs as expected okay and as you can see if i scroll this i'll scroll up a little bit so you can see so the first counter values we have the first uh invocation of first counter after it's been assigned to this this function up here it prints to screen one and then two on the second invocation and then we assign the uh second counter variable to another invocation of of the counter function and when we invoke second counter we get one printed out to the screen and then we get on the second invocation of second counter we get the number two printed out to the screen so this is an important property of uh function closures that if you want to persist data beyond when a function exits you can use a function closure so in this case we're we're using the first counter variable to continue to access the variables inside of this closure and those persist as long as we have access and we do with this first counter variable so as we invoke the first counter variable we are incrementing the same variables inside of this inside of this closure i hope these examples help you better understand function literals and closures in the go programming language and if you enjoyed the video please consider throwing a like on it and subscribing to the channel for more videos and if you have any questions comments or feedback please leave them below in the comments thanks for watching
Info
Channel: Tech and Beyond With Moss
Views: 455
Rating: undefined out of 5
Keywords: golang, go programming, go, function literals, closures, functions, go functions, go closures, function literal, golang tutorial, go tutorial, go programming language, golang tutorial for beginners, go tutorial for beginners, golang advanced
Id: EQAM0aWX2ck
Channel Id: undefined
Length: 11min 11sec (671 seconds)
Published: Mon Feb 15 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.