Golang Tutorial
Introduction Variables Constants Data Type Convert Types Operators If..Else Switch..Case For Loops Functions Variadic Functions Deferred Functions Calls Panic and Recover Arrays Slices Maps Struct Interface Goroutines Channels Concurrency Problems Logs Files and Directories Reading and Writing Files Regular Expression Find DNS records Cryptography Gotchas in Golang Import and Export Best Golang Packages Web Application Goroutines and Channels Exercises Reflection in Golang Golang for beginners Strings in Golang HTTP Client Server Examples Context PackageGolang Reference
Basic Programs Advance Programs Data Structure and Algorithms Date and Time Slice Sort, Reverse, Search Functions String Functions Methods and Objects Interface TypeBeego Framework
Beego Setup Beego Database Migration Beego GET POST Beego RoutingDeferred Functions Calls
Deferred Functions Calls
Go has a special statement called defer that schedules a function call to be run after the function completes. Consider the following example:
Example
package main
import "fmt"
func first() {
fmt.Println("First")
}
func second() {
fmt.Println("Second")
}
func main() {
defer second()
first()
}
This program prints First followed by Second.
A defer statement is often used with paired operations like open and close, connect and disconnect, or lock and unlock to ensure that resources are released in all cases, no matter how complex the control flow. The right place for a defer statement that releases a resource is immediately after the resource has been successfully acquired.
Below is the example to open a file and perform read/write action on it. In this example there are often spots where you want to return early.
Without defer
Example
func ReadWrite() bool {
file.Open("file")
if failureX {
file.Close() //And here...
return false
}
if failureY {
file.Close() //And here...
return false
}
file.Close() //And here...
return true
}
A lot of code is repeated here. To overcome this Go has the defer statement. The code above could be rewritten as follows. This makes the function more readable, shorter and puts the Close right next to the Open.
With defer
Example
func ReadWrite() bool {
file.Open("file")
defer file.Close() //file.Close() is added to defer list
// Do your thing
if failureX {
return false // Close() is now done automatically
}
if failureY {
return false // And here too
}
return true // And here
}
This has various advantages:
- It keeps our Close call near our Open call so it's easier to understand.
- If our function had multiple return statements (perhaps one in an if and one in an else), Close will happen before both of them.
- Deferred Functions are run even if a runtime panic occurs.
- Deferred functions are executed in LIFO order, so the above code prints: 4 3 2 1 0.
- You can put multiple functions on the "deferred list", like this example.
Example
package main
import "fmt"
func main() {
for i := 0; i < 5; i++ {
defer fmt.Printf("%d ", i)
}
}