Reputation: 2111
I would like to log a function's return values. The "smartest" thing I could come up with is wrapping my actual function body in a closure.
func foo(a int, b int) (int, error) {
c, err := func (a int, b int) (int, error) {
//...
return c, err
}(a, b)
fmt.Printf("%v %v %v %v", a, b, c, err)
return c, err
}
Is there a way to accomplish this with less boilerplate?
Upvotes: 0
Views: 1944
Reputation: 79584
There are two patterns I would consider:
As @Keeto suggests, you can use a 'defer' statement:
func foo(a, b int) (c int, e error) {
defer log.Printf("%v %v %v %v\n", a, b, c, err)
// ... the function body
}
A logging stub function:
func foo(a, b int) (int, error) {
c, err := realFoo(a, b)
log.Printf("%v %v %v %v\n", a, b, c, err)
}
func realFoo(a, b int) (int, error) {
// ... the function body
}
A closure also works, as you mentioned in your question, but in my opinion, that's the least readable of the options.
Which you choose depends mainly on preference. Performance should be roughly the same across the three options--but if performance is critical, do benchmarks to be sure, under your real application load.
Upvotes: 1
Reputation: 2612
Try this one: https://play.golang.org/p/VrPgH1VUwP
Basically, you just have to wrap them with some function that returns a function with the same signature but including the logging:
type fooFunc func(int, int) (int, error)
func fooLogger(f fooFunc) fooFunc {
return func(a, b int) (int ,error){
c, err := f(a, b)
log.Printf("%s => a: %v, b: %v, return => c: %v, err: %v\n", fnName(f), a, b, c, err);
return c, err
}
}
func foo(a, b int) (int, error){
c := a + b
return c, nil
}
func main() {
loggedFoo := fooLogger(foo)
//prints something like this
//2009/11/10 23:00:00 main.foo => a: 2, b: 2, return => c: 4, err: <nil>
c, err := loggedFoo(2, 2)
fmt.Println("from foo:", c, err)
}
Upvotes: 0
Reputation: 4198
Maybe I misunderstood your question, but what about:
package main
import (
"log"
)
func foo(a, b int) (c int, err error) {
defer func() {log.Printf("%v %v %v %v", a, b, c, err)}()
c = a + b
return c, nil
}
func main() {
foo(1, 3)
}
Upvotes: 2