Have you ever had the need to log final return values before a function returns? One way is to obviously log them just before return. But, they don't work in all the cases. Let me show you why.
First we'll take simple example of logging:
func minAndMax(arr []int) (min, max int){
min = arr[0]
max = arr[0]
for _, value := range arr {
if value < min {
min = value
}
if value > max {
max = value
}
}
log.Println("Returning", min, max)
return min, max
}
func main(){
var arr []int = []int{3,2,5,4,7,6}
minAndMax(arr)
}
This works as expected. But, it still needs us to track the end of function.
Also, as said before it doesn't work always. Let's see what happens with this example:
func changeBeforeReturn()(ret int) {
a := 1
defer func() {
ret++
}()
log.Println("Returning", a)
return a
}
func main(){
v := changeBeforeReturn()
log.Printf("%d", v)
}
You would expect the log in changeBeforeReturn
to print 1. But, your log in main
method prints 2!!😬😱😨
What happened? Well that's how the combination of defer and named return arguments works.
We can easily fix this, and the first issue of keeping track of last statement with a simple deferred printing statement using named return arguments:
func changeBeforeReturn()(ret int) {
a := 1
defer func() {
log.Println("Returning", ret)
}()
defer func() {
ret++
}()
return a
}
func main(){
v := changeBeforeReturn()
log.Printf("%d", v)
}
This correctly prints 2, not 1. Do make sure to write this deferred function before any other one.
Hope it helps... ☺️
Top comments (0)