在Go语言中记录多个返回值的日志。

huangapple go评论116阅读模式
英文:

Log multiple returned values in Go

问题

有没有一种惯用的方法来记录返回多个值的函数的结果?这段代码无法编译通过:

  1. import "log"
  2. func returnPair() (int, int) {
  3. return 42, 24
  4. }
  5. func main() {
  6. log.Printf("Returned %v", returnPair())
  7. }
  8. prog.go:7: multiple-value returnPair() in single-value context

更新摘要(特别感谢 @rvignacio):

这是Go语法中的一个特殊情况:

  1. func eat(args ...interface{}) {}
  2. func eatWithSpice(spice string, args ...interface{}) {}
  3. func main() {
  4. eat(returnPair()) // 这个可以工作
  5. eatWithSpice("pepper", returnPair()) // 这个不行
  6. }

作为一个特例,如果函数或方法g的返回值的数量与另一个函数或方法f的参数数量相等,并且可以分别赋值给f的参数,则调用f(g(parameters_of_g))将按顺序将g的返回值绑定到f的参数上。调用f除了调用g之外不能包含其他参数,而且g必须至少有一个返回值。如果f有一个最终的...参数,它将被赋予在分配了常规参数之后剩余的g的返回值。(http://golang.org/ref/spec#Calls)

英文:

Is there an idiomatic way to log result of a function returning multiple values? This won't compile:

  1. import "log"
  2. func returnPair() (int,int) {
  3. return 42, 24
  4. }
  5. func main() {
  6. log.Printf("Returned %v", returnPair())
  7. }
  8. prog.go:7: multiple-value returnPair() in single-value context

UPD summary (special thanks to @rvignacio):

This is a peculiarity in Go syntax:

  1. func eat(args ...interface{}) {}
  2. func eatWithSpice(spice string, args ...interface{}) {}
  3. func main() {
  4. eat(returnPair()) // this works
  5. eatWithSpice("pepper", returnPair()) // this does not
  6. }

As a special case, if the return values of a function or method g are equal in number and individually assignable to the parameters of another function or method f, then the call f(g(parameters_of_g)) will invoke f after binding the return values of g to the parameters of f in order. The call of f must contain no parameters other than the call of g, and g must have at least one return value. If f has a final ... parameter, it is assigned the return values of g that remain after assignment of regular parameters. (http://golang.org/ref/spec#Calls)

答案1

得分: 5

你可以先给这些返回值赋值:

  1. a, b := returnPair()
  2. log.Printf("返回值 %d %d", a, b)

你可以在"Go函数返回多个值的示例"中看到一个例子。

直接在Println中使用多个返回值也可以(因为它接受可变参数):

在你的情况下:play.golang.org

  1. package main
  2. import "log"
  3. func returnPair() (a int, b int) {
  4. return 42, 24
  5. }
  6. func main() {
  7. log.Println(returnPair())
  8. }

输出:

  1. 2009/11/10 23:00:00 42 24
英文:

You can assign those returning values first:

  1. a, b := returnPair()
  2. log.Printf("Returned %d %d", a, b

You can see an example in "Multiple return values from Go functions".

Using a multiple returning value directly in Println works though (since it accepts variadic parameters):

In your case: <kbd>play.golang.org</kbd>

  1. package main
  2. import &quot;log&quot;
  3. func returnPair() (a int, b int) {
  4. return 42, 24
  5. }
  6. func main() {
  7. log.Println(returnPair())
  8. }

Output:

  1. 2009/11/10 23:00:00 42 24

答案2

得分: 2

我同意VonC的方法,它更加简洁,但如果你真的想要的话,你可以受到Must()这种函数的启发,做出类似下面这样的代码:

  1. package main
  2. import "fmt"
  3. func returnPair() (int, int) {
  4. return 42, 24
  5. }
  6. func displayPair(a, b interface{}) string {
  7. return fmt.Sprint(a, b)
  8. }
  9. func main() {
  10. fmt.Printf("pair: %v\n", displayPair(returnPair()))
  11. }

编辑:

或者更通用一些:

  1. package main
  2. import "fmt"
  3. func returnPair() (int, int) {
  4. return 42, 24
  5. }
  6. func returnTriple() (int, int, int) {
  7. return 42, 24, 10
  8. }
  9. func displayPair(elem ...interface{}) string {
  10. return fmt.Sprint(elem...)
  11. }
  12. func main() {
  13. fmt.Printf("pair: %v, triple %v\n", displayPair(returnPair()), displayPair(returnTriple()))
  14. }
英文:

I aprrove the method of VonC, which is cleaner, but if you really want, you can get inspired by the Must() kind of function and do something like this:

http://play.golang.org/p/_dik4rSFBC

  1. package main
  2. import &quot;fmt&quot;
  3. func returnPair() (int, int) {
  4. return 42, 24
  5. }
  6. func displayPair(a, b interface{}) string {
  7. return fmt.Sprint(a, b)
  8. }
  9. func main() {
  10. fmt.Printf(&quot;pair: %v\n&quot;, displayPair(returnPair()))
  11. }

EDIT:

Or more generic:

http://play.golang.org/p/DjPur-aatt

  1. package main
  2. import &quot;fmt&quot;
  3. func returnPair() (int, int) {
  4. return 42, 24
  5. }
  6. func returnTriple() (int, int, int) {
  7. return 42, 24, 10
  8. }
  9. func displayPair(elem ...interface{}) string {
  10. return fmt.Sprint(elem...)
  11. }
  12. func main() {
  13. fmt.Printf(&quot;pair: %v, triple %v\n&quot;, displayPair(returnPair()), displayPair(returnTriple()))
  14. }

huangapple
  • 本文由 发表于 2014年7月31日 02:30:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/25044309.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定