cover image for article

Golang: Defer

Edit

Published on June 29, 2022

Author: Meet Rajesh Gor

#go

Introduction

In this part of the series, we will be taking a look at the defer keyword in golang. The defer keyword is used for delaying the function call in a particular block of program(function or a loop).

Defer Keyword

The defer keyword is an interesting keyword in golang, it basically holds up the execution of the statement until all the statements around the local scope has been executed. It is basically like a stack holding the execution of statements. You can have multiple defer keywords in the single code block(function or a loop), those will be called by the principle of first in last out.

So, let's take a simple example, the syntax is quite simple just add defer before the statement you want to hold up.


go
package main

import "fmt"

func main() {
	fmt.Println("First")
	defer fmt.Println("Second Ahhh..")
	fmt.Println("Third")
}

go run defer.go                                                                                                               

First
Third
Second Ahhh..

As, you can see the function call Second was executed at the end of all the function calls in the main function. This is because of the defer keyword. It will halt or postpone the calling of a statement/function before all the statements have bee executed in the local scope. This keyword can be stacked for calling different statements at the specific time in the state of the program.

Multiple defer keyword

We can understand the defer keyword in a better way if we modify the previous example a bit. We will use multiple defer statements in it for understanding the flow of the program.


go
package main

import "fmt"

func main() {
	fmt.Println("bag")
	defer fmt.Println("book")
	defer fmt.Println("cap")
	fmt.Println("laptop")
	defer fmt.Println("wallet")
	fmt.Println("headphones")
}

go run defer.go                                                                                                            

bag
laptop
headphones
wallet
cap
book

Here, we can see that the bag is printed out first, then laptop and then headphones, but after these, we have maintained a stack for calling out the defer statements.

Initially, consider a empty stack [] for storing defer statements. Firstly, the bag statement will be printed. After printing the bag keyword, there is a defer key word, so we add the statement to the stack ["book"]. Just for convenience, ignore the function syntax and the actual statements, just focus on what is printed when. So, we have printed bag and we have stack as ["book",]. We again encounter a defer keyword, so we push the statement cap into the stack ["book", "cap",]. Further, we encounter the normal statement, so we print "laptop". Next up, we encounter a defer keyword and thereby we push "wallet" into the stack, which then becomes ["book", "cap", "wallet"]. The last statement in the main function is "headphones", so we print "headphones" with the Println function. Since, there are no further statements to execute in the main function, we start poping out the function calls from the stack. Remember last in first out, so we will print the statement which were pushed last into the stack. Since the stack is ["book", "cap", "wallet"], so we will pop out "wallet" from the stack since we have pushed it last in the stack. Thereby we print "wallet" after "headphones" and the stack now becomes ["book", "cap"]. Next, we have to pop out the second last element that we pushed into the stack which was "cap", thus we print "cap". The stack only has one element in the stack and we pop out that as well which is "book". So, this is how the defer keyword stacks up in golang.

NOTE: The defer keyword calls functions after the execution of all other functions in it's scope but the parameters are evaluated before handed which means just the function is executed later, but the parameters are already loaded

defer keyword in function call

The defer keyword is quite similarly used while calling the functions. The fmt.Println is also a function, but writing custom functions gives a different feeling to us.


go
package main

import "fmt"

func square(x int) int {
	fmt.Println(x * x)
	return x * x
}

func main() {
	// defer keyword in function
	defer square(12)
	defer square(10)
	square(15)
}

go run defer.go                                                                                                            

225
100
144

So, we have created the square function and called it thrice and twice we have used the defer keyword. The defer keyword first pushes the function call square(12) to the stack, so the stack is [square(12) ]. Next, we again have the defer keyword, so we push the square(10) to the stack which becomes [square(12) square(10)]. The next statement is immediately called the function square(15) and thereby we end the main function. So, we have to pop the function calls from the stack. The last element square(10) is called first and then the only call to the square(12). Thereby, the order of the calling becomes 225 100 144.

That's it from this part. Reference for all the code examples and commands can be found in the 100 days of Golang GitHub repository.

Conclusion

So, from this post, we were able to understand the defer keyword in golang. We were able to explore how we can delay the calling of a function in a particular scope of the program.

Thank you for reading, if you have any queries, feedback, or questions, you can freely ask me on my social handles. Happy Coding :)