In this tutorial, you will learn about defer statements in the Go programming language. From the previous tutorial, you learned control flow statements like if, switch, for loop, for –range loop that are most common in other programming languages. But defer in Golang is not common like other control flow statements.
The word defer means “put off (an action or event) to a later time or postpone “.In the Go programming language, a statement with defer
keyword specifies that a particular statement needs to be postponed or execute sometime later but should be before exiting from the main loop.
defer
keyword till the end of calling functionIt is implemented as a stack data structure, all the functions are called on the stack in the last in first out manner except the defer keyword function call. It is called only after the last function call is returned.
In a normal Go application or program, control flows from top to bottom of any function that we call. Generally, a function starts from the first line and executes through until it gets to the last line.
Let us just understand the same with a program. When we run the below code it just runs in sequential order and prints the output as “first”, “second”, “third”.
package main
import "fmt"
func main() {
fmt.Println("First")
fmt.Println("Second")
fmt.Println("Third")
}
Output:
First Second Third
The defer keyword
is used to differ the execution of statements. Suppose if defer keyword is placed in front of fmt.Println("Second")
you will notice that the second will be printed after the third.
package main
import "fmt"
func main() {
fmt.Println("First")
defer fmt.Println("Second") //defer keyword
fmt.Println("Third")
}
Output:
First Second Third
The defer keyword executes any functions that are passed into it after the function finishes its final statement but before it actually returns. So the way the main function ( ) is executed is it prints the first statement output in the above example “first”. Then in the next statement recognize a defer keyword in function call then print the last statement “third”. Then finally the main function ( ) exits & check if there are any deferred functions to call. Since there is one defer function, go ahead and call that function.
The key advantage of deferring keywords in the Go programming language is for resource clean-up like open files, to handle database, network connections, etc. Once after the termination of a program in execution using certain resources for successful completion of a program, there is a need to close each resource used to avoid resource conflict when some other programs are waiting for the same resources.
Defer statement makes the Go code error-free by closing all the files or resources that are opened during program execution.
In Go defer resource clean-up is often. Let us understand with an example how to defer a statement while writing to a file. Once after opening a file it needs to close.
package main
import (
"fmt"
"log"
"os"
)
func main() {
err := writeToFile("Some text")
if err != nil {
log.Fatalf(err.Error())
}
fmt.Printf("Write to file succesful")
}
func writeToFile(text string) error {
file, err := os.Open("temp.txt")
if err != nil {
return err
}
n, err := file.WriteString("Some text")
if err != nil {
return err
}
fmt.Printf("Number of bytes written: %d", n)
file.Close()
return nil
}
The above-given Go code opens a file. The function writeToFile
opens a file & writes some information/contents to the file. After finishing writing to a file the next step is to close the file. There is a chance of the occurrence of an error during a write operation. In such a case, it will return an error and exit the function. The function tries to close the file and resources used are released back to the system. Finally returns a nil
value after successful completion of writing to a file.
The function call to file.WriteString
fails, the function will return without closing the file and releases the resource back to the system. This problem can be fixed using defer keyword instead of using a file.Close()
statement. The defer keyword executes before the function returns to avoid or fix such problems.
After rewriting the above code looks like
package main
import (
"fmt"
"log"
"os"
)
func main() {
err := writeToFile("Some text")
if err != nil {
log.Fatalf(err.Error())
}
fmt.Printf("Write to file succesful")
}
func writeToFile(text string) error {
file, err := os.Open("temp.txt")
if err != nil {
return err
}
defer file.Close() //defer statement
n, err := file.WriteString("Some text")
if err != nil {
return err
}
fmt.Printf("Number of bytes written: %d", n)
return nil
}
The defer file.Close ()
closes the file after a file is opened. This defers the file.close() ensures closing of a file is carried out through the write to same file results in some error.
A Golang can have multiple defer keywords used inside a program. Let us check it with the below given example where three defer statements are executed. The concept of the stack works here.
These are pushed onto a stack. The top position holds the last print statement i.e., third.
Observe the output for the below code it is printed reverse order just as it is pushed onto the stack. The deferred statements occupy in reverse order one above the previous one which results in Last In, First Out manner.
package main
import "fmt"
func main() {
defer fmt.Println("First")
defer fmt.Println("Second")
defer fmt.Println("Third")
}
Output:
First Second Third
Defer arguments are evaluated during the time when defer statements are evaluated.
Let us understand with a simple program
package main
import "fmt"
func main() {
statement := "Go language in Learn eTurorials"
defer fmt.Printf("In defer statement is: %s\n", statement)
statement = "Learn eTurorials"
}
Output:
In defer statement is: Go language in Learn eTurorials
In the given program a variable statement
of string data type is considered as of defer statement. The defer statement is evaluated with a value Go language in Learn eTutorials
assigned to the variable statement. The defer statement prints the value of the variable statement
. Later in the next line changes the value of the statement variable with “Learn eTutorials
”. You can see the output of the above code evaluate defer statement variable only, though the value assigned to the same variable is undergone a change.