Golang日志函数返回参数

时间:2017-10-12 20:48:29

标签: logging go

我想记录函数的返回值。我能想到的“最聪明”的东西是将我的实际函数体包装在一个闭包中。

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
}

有没有办法用更少的样板来实现这一目标?

3 个答案:

答案 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)

我会考虑两种模式:

  1. 正如@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
    }
    
  2. 记录存根函数:

    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
    }
    
  3. 正如您在问题中提到的那样,闭包也有效,但在我看来,这是最不可读的选项。

    您选择的主要取决于偏好。在三个选项中,性能应该大致相同 - 但如果性能至关重要,请在实际应用程序负载下确保基准测试。