如何解析golang中的多个收益

时间:2018-10-04 19:23:11

标签: python go

我有一个go函数,该函数返回两个整数值。下面是功能

func temp() (int, int){
 return 1,1
}

是否可以将temp函数直接放入Println并使用以下字符串格式打印两个输出

fmt.Println("first= %d and second = %d", temp() ) // This doesn't work

在Python中,我可以执行以下操作

def func():
    return 1,1
print("{0}={1}".format(*func())
>> '1=2'

我还能在golang中做类似的事情吗?

3 个答案:

答案 0 :(得分:5)

否,这是不可能的。您必须将多值表达式中的所有值分配给单独的变量才能使用它们,例如:

a, b := temp()
fmt.Println("first = %d and second = %d", a, b)
// first = 1 and second = 1

[编辑]

有趣的是,在某些情况下,如果参数类型和Arity匹配,或者对于纯可变参数(Go Playground),您可以将多值表达式用作函数调用参数:

func oneTwo() (int, int) {
  return 1, 2
}

func incr2(x, y int) (int, int) {
  return x + 1, y + 1
}

func main() {
  incr2(oneTwo()) // OK: multi-value return and arguments match.

  fmt.Println(oneTwo()) // OK: pure variadic function.

  fmt.Printf("%d %d", oneTwo()) // ERR: mixed formal and variadic args.
}

答案 1 :(得分:3)

首先,对于您尝试做的事情,应该使用fmt.Printf()而不是fmt.Println(),因为前者会期望并使用格式字符串。

展望未来,默认情况下不支持此操作,因为引用Spec: Calls:

  

在特殊情况下,如果一个函数或方法g的返回值相等,并且可以分别分配给另一个函数或方法f的参数,则调用{{1} }将f(g(parameters_of_g))的返回值按顺序绑定到f的参数后,将调用gf的调用必须不含除f的调用之外的任何参数,并且g必须具有至少一个返回值。如果g有一个最终的f参数,它被分配了...的返回值,这些返回值在分配常规参数后仍然保留。

g的签名为:

fmt.Printf()

除了函数调用(调用的返回值)之外,您无法将其他参数传递给func Printf(format string, a ...interface{}) (n int, err error)

请注意,fmt.Printf()的签名是:

fmt.Println()

这意味着func Println(a ...interface{}) (n int, err error) 可以正常工作,其他至少具有一个返回值的函数也可以工作,因为引号的最后一句允许这样做(“如果fmt.Println(temp())具有最后一个f参数,它被分配了...的返回值,这些返回值在分配常规参数后仍然保留。”

但是,通过一些技巧,我们也可以通过g实现您想要的。

请注意,如果fmt.Printf()返回类型为temp()的值,我们可以使用[]interface{}将其作为某些可变参数的值传递。

这意味着有效:

...

它可以正确打印(在Go Playground上尝试):

func main() {
    fmt.Printf("1: %v, 2: %v\n", temp()...)
}

func temp() []interface{} { return []interface{}{1, 2} }

因此,我们只需要一个实用函数即可将任何函数的返回值包装到1: 1, 2: 2 中,因此我们可以使用它传递给[]interface{}

这简直太简单了:

fmt.Printf()

如上所述(使用func wrap(vs ...interface{}) []interface{} { return vs } ),我们可以将至少具有1个返回值的任何函数的返回值传递给fmt.Println()作为其输入参数的值。

现在使用此wrap()函数,请参见以下示例:

wrap()

这有效,并输出(在Go Playground上尝试):

func main() {
    fmt.Printf("1: %v\n", wrap(oneInt())...)
    fmt.Printf("1: %v, 2: %v\n", wrap(twoInts())...)
    fmt.Printf("1: %v, 2: %v, 3: %v\n", wrap(threeStrings())...)
}

func oneInt() int { return 1 }

func twoInts() (int, int) { return 1, 2 }

func threeStrings() (string, string, string) { return "1", "2", "3" }

有关该主题的更多信息,请参见相关问题:

Multiple values in single-value context

Return map like 'ok' in Golang on normal functions

答案 2 :(得分:0)

当我不使用以下任何字符串格式时,我可以打印它

fmt.Println(temp())

Println仅支持此功能,printf不支持