我想记录函数的返回值。我能想到的“最聪明”的东西是将我的实际函数体包装在一个闭包中。
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
}
有没有办法用更少的样板来实现这一目标?
答案 0 :(得分:2)
也许我误解了你的问题,但是:
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)
}
答案 1 :(得分:0)
试试这个:https://play.golang.org/p/VrPgH1VUwP
基本上,你只需要用一些函数来包装它们,这些函数返回一个具有相同签名但包含日志记录的函数:
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)
}
答案 2 :(得分:0)
我会考虑两种模式:
正如@Keeto建议的那样,您可以使用'延迟'语句:
func foo(a, b int) (c int, e error) {
defer log.Printf("%v %v %v %v\n", a, b, c, err)
// ... the function body
}
记录存根函数:
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
}
正如您在问题中提到的那样,闭包也有效,但在我看来,这是最不可读的选项。
您选择的主要取决于偏好。在三个选项中,性能应该大致相同 - 但如果性能至关重要,请在实际应用程序负载下确保基准测试。