DEV Community

Nitin Bansal
Nitin Bansal

Posted on

Simple way of logging return values of any function

#go

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)
}
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

This correctly prints 2, not 1. Do make sure to write this deferred function before any other one.

Hope it helps... ☺️

Discussion (0)