Defer, Panic and Recover Control flow Concepts in Go

Muhammed Ali
Analytics Vidhya
Published in
3 min readJun 15, 2021

Introduction

Defer, Panic and Recover are essential concepts when developing Go applications. With the defer function, you are able to call a function but prevent execution until some other functions are executed. If you are familiar with Python language, the defer function is similar to finally keyword in Python.
For your Go application to panic, it has to come to a point where it cannot run anymore because it doesn't know what to do. This can be triggered by the compiler or manually in our code.
As for the recover keyword, it is closely related with panic. When a program enters a panic state we have an option to help it recover from that, we use the recover keyword.

In this article, you will learn how defer, panic and recover functions work, its properties, and use-cases.

Prerequisites

  1. Basic knowledge of Golang

Defer

The defer statement enables you to prevent the execution of a function until a later time, depending on what you are trying to accomplish.
Using a real-world example, growing up every guy has the ability to grow beards but that ability is held for some reason till you are older. Basically, that is how defer works.

Properties

  1. Defer statement doesn’t run a function, it runs the function call.
  2. It follows last in, first out order, i.e., the last defer statement that is called will be the first to be executed.

How to use Defer

package main
import("fmt")
func main() {
fmt.Println("one")
defer fmt.Println("three")
fmt.Println("two")
}

output:

one
two
three

Notice that three was printed last. This is because any statement that is preceded by the defer keyword isn’t invoked until the end of the function in which defer was used.

package main
import("fmt")
func main() {
defer fmt.Println("one")
defer fmt.Println("two")
defer fmt.Println("three")
}

output:

three
two
one

As stated in the property above, the first defer statement to be called is the last to be executed.

Panic

panic is a built-in function that stops the control flow of your program. This can be done by the compiler or added manually to your code flow.
We use panic statements when your application enters a state that it cannot recover from. Example: Trying to divide a number by 0.
They occur when the program can’t continue at all.

Properties

  1. Panics happen after a deferred statement is executed.
  2. the program ends after the panic statement is run.

How to use Panic

package main
import "fmt"
func main(){
fmt.Println("one")
defer fmt.Println("three")
panic("a panic happened")
fmt.Println("four")
}

Output:

one
three
panic: a panic happened

As you can see above, because of the panic we invoked in the code compiler didn’t execute the rest of the program.

Another example:

package mainimport "fmt"func main() {
x := 0
y := 20
fmt.Println(y/x)
}

Output:

panic: runtime error: integer divide by zero

goroutine 1 [running]:
main.main()
/tmp/sandbox064477089/prog.go:8 +0x11

The output above shows that instead of the defer statement to be run last, it is executed first before the panic happened. Note: the Go compiler can also invoke panic.

Recover

recover function is used to recover function from panic. Recover is only useful inside deferred functions. In a normal execution, a call to recover will returnniland have no other effect. Arecover function should always be called inside a defer function because the deferred function does not stop its execution if the program panics, so the recover function stops the panicking.

Properties

  1. Recovery statements are used to come out of a panic
  2. Useful inside deferred functions. This is because when an application panics, it no longer executes the rest of the program except for deferred functions.

How to use Recover

package mainimport "fmt"func main() {
x := 0
y := 20
printAllOperations(x, y)
}
func printAllOperations(x int, y int) {defer func() {
// defer function to escape the panic when y/x runs
if r := recover(); r != nil {
fmt.Printf("Recovering from panic in printAllOperations error is: %v \n", r)
fmt.Println("Proceeding to alternative flow skipping division.")
printOperationsSkipDivide(x, y)
}
}()
sum, divide, multiply := x+y, y/x, x*y
fmt.Printf("sum=%v, divide=%v, multiply=%v \n", sum, divide, multiply)
}
func printOperationsSkipDivide(x int, y int) {
sum, multiply := x+y, y*x
fmt.Printf("sum=%v, multiply=%v \n", sum, multiply)
}

output:

Recovering from panic in printAllOperations error is: runtime error: integer divide by zero 
Proceeding to alternative flow skipping division.
sum=20, multiply=0

20/0 caused panic in the Go compiler so it invoked the defer function which printed the results of the rest of the results

Conclusion

In this tutorial, we are able to figure out how the defer, recover, and panic functions are used in a Golang application. I hope this guide helps you write better Golang with those functions.

--

--

Muhammed Ali
Analytics Vidhya

Technical Writer with experience in building awesome stuff with Django, Python, JavaScript, React, Kubernetes, etc. || Cloud-Native enthusiast.