Defer is one of my favorite things in Go. You can use it to make sure operation is executed before a function returns. It is very useful. I think almost all Go programmer, if not all, has used defer
statement in their application. But there is one thing you should know before using defer in Go.
So what is it that you should know before using defer? It is that the deferred function’s parameter is evaluated immediately even though the function is executed before the containing function returns. It is written in the specification and in the Tour of Go, but I think some of the people that use defer
didn’t know it at first (including me haha). So what does it mean? Let’s see it in action.
I use this code to try it:
func myFunc() {
myStr := "intial"
defer deferedFunc(myStr)
myStr = "altered"
fmt.Println("myFunc's myStr: ", myStr)
}
func deferedFunc(str string) {
fmt.Println("deferedFunc's str: ", str)
}
There are two functions, myFunc
and deferedFunc
. The myFunc
declare and initiate a string variable, then use defer with the string as a parameter to deferedFunc
, then change the value of the string and print the value of the string. The deferedFunc
will print the given parameter.
Run the code and I got this in the terminal:
myFunc's myStr: altered
deferedFunc's str: intial
fmt.Println
in the deferedFunc
is executed last, but it has the parameter of the initial string value. The string’s value is changed before the deferred function is called, but the deferred function got the initial value because it is evaluated immediately when defer is used.So what if we want to pass the latest value to the deferedFunc
? To do this, We can defer anonymous function that call the deferedFunc
.
func myFunc() {
myStr := "intial"
defer func() {
deferedFunc(myStr)
}()
myStr = "altered"
fmt.Println("myFunc's myStr: ", myStr)
}
func deferedFunc(str string) {
fmt.Println("deferedFunc's str: ", str)
}
myFunc's myStr: altered
deferedFunc's str: altered
I think this is important to know because you can avoid unexpected bugs when using defer. You can also share this information with others and prevent your colleagues to make unexpected bugs.