Log multiple returned values in Go
Asked Answered
M

2

7

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

import "log"
func returnPair() (int,int) {
    return 42, 24
}
func main() {
    log.Printf("Returned %v", returnPair())
}

prog.go:7: multiple-value returnPair() in single-value context

UPD summary (special thanks to @rvignacio):

This is a peculiarity in Go syntax:

func eat(args ...interface{}) {}

func eatWithSpice(spice string, args ...interface{}) {}

func main() {
    eat(returnPair()) // this works
    eatWithSpice("pepper", returnPair()) // this does not
}

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)

Monte answered 30/7, 2014 at 18:30 Comment(3)
According to the spec, eatWithSpice("pepper", returnPair()) isn't an inconsistence, it should be eatWithSpice("pepper", returnPair()...)Splashdown
@Splashdown Does not work: play.golang.org/p/fz-452hKT7Monte
Sorry, I missed you were returning multiple values, here's the correct explanation: "As a special case, if the return parameters 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. No other special cases for function calls are allowed."Splashdown
B
6

You can assign those returning values first:

a, b := returnPair()
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: play.golang.org

package main

import "log"

func returnPair() (a int, b int) {
    return 42, 24
}
func main() {
    log.Println(returnPair())
}

Output:

2009/11/10 23:00:00 42 24
Beniamino answered 30/7, 2014 at 18:35 Comment(2)
This is exactly what I want to avoidMonte
@grep I have added the other approach: using directly PrintlnBeniamino
K
2

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

package main

import "fmt"

func returnPair() (int, int) {
    return 42, 24
}

func displayPair(a, b interface{}) string {
    return fmt.Sprint(a, b)
}

func main() {
    fmt.Printf("pair: %v\n", displayPair(returnPair()))
}

EDIT:

Or more generic:

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

package main

import "fmt"

func returnPair() (int, int) {
    return 42, 24
}

func returnTriple() (int, int, int) {
    return 42, 24, 10
}

func displayPair(elem ...interface{}) string {
    return fmt.Sprint(elem...)
}

func main() {
    fmt.Printf("pair: %v, triple %v\n", displayPair(returnPair()), displayPair(returnTriple()))
}
Kuhns answered 30/7, 2014 at 18:38 Comment(2)
This looks good enough: fmt.Printf("returned %v", fmt.Sprint(returnPair()))Monte
Lol, indeed, much simpler :p. Don't know why I called a displayPair in my second example ^^Kuhns

© 2022 - 2024 — McMap. All rights reserved.