Table of contents
1.
Introduction
2.
Defer
2.1.
Example:
3.
Multiple defer statements
3.1.
Defer and return 
4.
How to clean up resources using defer?
5.
FAQs
6.
Key Takeaways
Last Updated: Mar 27, 2024

Defer in Go

Author Yashesvinee V
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

A Go program uses many resources like open files, database handles and network connections when it is running. It is essential to close those resources to avoid exhausting them and allow other functions to utilise them. As a programmer, one must make sure to clean up the resources used and keep the code clean. The defer statements of Golang help carry out the above operations and is extremely useful.

Defer

Defer means to put off an event or action to a later time. The defer keyword does exactly this in Golang. 

Syntax for using defer in a statement:

defer statement;

 

Syntax for using defer in functions:

defer func func_name(parameter_list Type)return_type{
// Code
}

defer func (receiver Type) method_name(parameter_list){
// Code
}

defer func (parameter_list)(return_type){
// Code
}()

 

Any statement that uses defer is postponed until the end of a function. After executing all statements in the function, the defer statement is executed. Let’s understand this using a simple example.

package main

import "fmt"

func main(){
   defer fmt.Println("Line b")
   fmt.Println("Line a")
}

 

Output:

Line a
Line b

 

The use of defer in the first line of the main function causes that statement to be postponed until the end of the function. Hence, it is executed in the last.

In practical applications, defer is used in functions to clean up its resources.

Here are a few key points to remember about the defer keyword.

  • The defer keyword allows the code execution in a LIFO order, last-in-first-out. This statement adds the function call following the defer keyword onto a stack. All of the calls on that stack are called when the function in which they were called returns.
     
  • The arguments to the deferred function are evaluated on execution and not its call.
     
  • The defer function will not be called when a call is made to it directly; rather, a call made to a statement next to the defer function can cause its execution.
     
  • The execution of a deferred function is delayed until the surrounding function returns.
     
  • A deferred function will be executed even if the enclosing function terminates abruptly.

Example:

package main

import "fmt"

func calc(a, b int) int{
   res := a * b
   fmt.Println("Product: ", res)
   return 0
}

func show(){
   fmt.Println("The product of two numbers.")
}

func main(){
   defer calc(23, 56)
   show()
}

 

Output:

The product of two numbers.
Product: 60

Multiple defer statements

package main

import "fmt"

func main(){
   defer fmt.Println("Defer-main")
   fmt.Println("Start main")
   f1()
   fmt.Println("Finish main")
}

func f1(){
   defer fmt.Println("Defer-f1")
   fmt.Println("Start f1")
   f2()
   fmt.Println("Finish f1")
}

func f2(){
   defer fmt.Println("Defer-f2")
   fmt.Println("Start f2")
   fmt.Println("Finish f2")
}

 

Output:

Start main
Start f1
Start f2
Finish f2
Defer-f2
Finish f1
Defer-f1
Finish main
Defer-main

 

In the above example, every defer statement encountered is placed in a stack and executed in that order. The defer in the main function is the first stack element, followed by f1 and then f2. Once the contents of f2 are completely executed, the defer statement of f2 is first executed, followed by f1 and then main.

Defer and return 

package main
import "fmt"

func main(){
   result := f1()
   fmt.Println(result)
}

func f1() (v int){
   defer func() { v = 50 }()
   v = 100
   return
}

 

Output:

50

 

Function f1 contains a deferred inline function that assigns 50 to variable v. The first line to be executed in f1 is the assignment of 100 to v. The use of return statement should cause the control to return back to main. However, this is not the case. The deferred inline function is executed after the return statement, which changes the value of v.

How to clean up resources using defer?

Consider the following example that uses the defer statement to close a file that was opened to write some data into it.

package main

import (
"io"
"log"
"os"
)

func main(){
   if err := write("readme.txt", "This is a readme file"); err != nil 
   {
      log.Fatal("failed to write file:", err)
   }
}

func write(fileName string, text string) error{
   file, err := os.Create(fileName)
   if err != nil 
   {
      return err
   }
   defer file.Close()
   _, err = io.WriteString(file, text)
   if err != nil 
   {
      return err
   }
   return nil
}

 

The main function calls a write function to open a file and write a given text. Any errors that may arise during this operation is to be displayed. The write function creates a new file with the given name. The defer statement is postponed until the end of the write function. The line of text is written into the opened file. The defer statement that finally closes the file is executed after encountering any of the three return statements used. This ensures that opened file is closed before returning to the main function for further instructions.

This way, multiple defer statements can be used to close multiple open resources after its operation.

FAQs

 1. What is the need for defer statements?

When dealing with multiple functions that use variable resources for their operations, it is hard to keep track if the resources that are no longer necessary are closed or not. Using defer helps close all open resources without fail before moving on to another operation.
 

 2. What are functions in Go?

Like any other programming language, functions in Go contain instructions to perform a particular task. Go supports ‘First class functions’, i.e. they can be assigned to variables, passed as arguments to another function and be returned from another function.

Key Takeaways

This article extensively discusses the defer keyword in Golang. We hope that this blog has helped you enhance your knowledge about the working and use of the defer statements. If you would like to learn more, check out our articles on the Coding Ninjas Library. Do upvote our blog to help other ninjas grow. Happy Coding!

Related Links:

What is Golang?

Dynamics of Golang

Live masterclass