The defer function in Go allows you to delay the execution of a function until the other function exits. In most cases, we use the defer keyword to delay the execution of a function later in the program for cleanup. An example would be to close a file, close a channel, or close a mutex. This isn’t different if you are familiar with the finally or ensure in other programming languages.

Let us use this guide to learn how to use the defer keyword in Go.

Golang Defer Keyword.

To add defer mechanism to a function, use the defer keyword followed by the function or method name. An example code is as shown:

package main


import “fmt”


func main() {


    fmt.Println(“I run first”)


    defer fmt.Println(“I run last”)


    fmt.Println(“I run second”)

}

In the above example, we use the defer keyword to words to delay the function’s execution on the fourth line. This means that this function will execute last.

An example output is as shown:

$ go run defer.go


I run first


I run second


I run last

This means that the method only runs after all other methods returns.

Keep in mind that the function or method called with a defer keyword will run as long as the other methods/functions return. The return can either be through a panic or normal execution.

Consider the example below where a method is called despite a panic.

package main

import “fmt”


func main() {


    defer fmt.Println(“I run”)


    panic(“Panic!!!”)


    fmt.Println(“I dont run”)

}

The above code should return:

I run


panic: Panic!!!


goroutine 1 [running]:


main.main()


      0x73

exit status 2

Order of Execution

The arguments of a deferred function are evaluated immediately, although the execution is delayed until the surrounding function returns.

If you have more than one deferred function call, Go organizes them in a list and executes them in Last-In-First-Out order (LIFO).

We can illustrate this using a simple for loop as shown below:

package main


import “fmt”


func main() {


    fmt.Println(“I start”)


    for i := 1; i <= 5; i {


        defer fmt.Println(i)


    }


    fmt.Println(“I second”)

}

We can see the order of execution in the output:

Use Defer Function to Return a Value

You can use an anonymous deferred function to access and change the return parameters of the surrounding function.

An example is as shown:

func say() (str string) {


    defer func() {


        str = “Goodbye”


    }()


    return “Hello!”

}

In this example, the function returns the string “Goodbye” instead of “Hello”.

Defer Practical Use – Close File

A real-world use case of the defer keyword is to close a file. Take the example shown below:

file, err := os.Open(“hello.txt”)

if err != nil {


    log.Fatal(err)

}


defer file.Close()


scanner := bufio.NewScanner(file)


scanner.Split(bufio.ScanWords)

for scanner.Scan() {


    fmt.Println(scanner.Text())

}

if err := scanner.Err(); err != nil {


    log.Fatal(err)

}

We open the file to read using the Open() method in the example above. We then use the defer keyword to delay the close operation after the reading operation is completed.

Conclusion

In this article, we discuss how the to defer keyword works and how we can use it to delay the execution of a function.

Thanks for reading!!

About the author

<img data-del="avatar" data-lazy-src="https://kirelos.com/wp-content/uploads/2022/02/echo/john-150×150.png621352aa3b5fc.jpg" height="112" src="data:image/svg xml,” width=”112″>

John Otieno

My name is John and am a fellow geek like you. I am passionate about all things computers from Hardware, Operating systems to Programming. My dream is to share my knowledge with the world and help out fellow geeks. Follow my content by subscribing to LinuxHint mailing list