InA*_*ash 3 python return-value variadic go multiple-return-values
我有一个go函数,它返回两个整数值.以下是功能
func temp() (int, int){
return 1,1
}
Run Code Online (Sandbox Code Playgroud)
是否可以将temp函数直接放入a Println并使用字符串格式打印输出,如下所示
fmt.Println("first= %d and second = %d", temp() ) // This doesn't work
Run Code Online (Sandbox Code Playgroud)
在Python中,我能够执行以下操作
def func():
return 1,1
print("{0}={1}".format(*func())
>> '1=2'
Run Code Online (Sandbox Code Playgroud)
我可以在golang做类似的东西吗?
前言:我在 中发布了此实用程序github.com/icza/gox,请参阅gox.Wrap()。
首先,对于您尝试执行的操作,您应该使用fmt.Printf()而不是fmt.Println()仅像前者所期望的那样使用格式字符串。
展望未来,这在默认情况下不受支持,因为引用自Spec: Calls:
作为一种特殊情况,如果一个函数或方法的返回值
g在数量上相等并且可以单独分配给另一个函数或方法的参数f,那么调用f(g(parameters_of_g))将f在将 的返回值绑定g到 的参数后调用f。除了调用 之外, 的调用f不得包含任何参数g,并且g必须至少有一个返回值。如果f有一个最终...参数,则将其分配给g常规参数分配后剩余的返回值。
并fmt.Printf()有以下签名:
func Printf(format string, a ...interface{}) (n int, err error)
Run Code Online (Sandbox Code Playgroud)
fmt.Printf()除了函数调用(调用的返回值)之外,您不能传递其他参数。
请注意,的签名fmt.Println()是:
func Println(a ...interface{}) (n int, err error)
Run Code Online (Sandbox Code Playgroud)
这意味着可以fmt.Println(temp())工作,对于任何其他至少具有一个返回值的函数也是如此,因为引用部分的最后一句允许这样做(“如果f有一个最终...参数,则g在分配常规参数。” )
但是通过一个小技巧,我们也可以实现您想要的fmt.Printf()。
请注意,如果temp()将返回一个 type 值[]interface{},我们可以...将其作为某个可变参数的值传递。
这意味着这有效:
func main() {
fmt.Printf("1: %v, 2: %v\n", temp()...)
}
func temp() []interface{} { return []interface{}{1, 2} }
Run Code Online (Sandbox Code Playgroud)
它可以正确打印(在Go Playground上尝试):
1: 1, 2: 2
Run Code Online (Sandbox Code Playgroud)
所以我们只需要一个实用函数,它将任何函数的返回值包装到 a 中[]interface{},这样我们就可以使用它来传递给fmt.Printf().
它非常简单:
func wrap(vs ...interface{}) []interface{} {
return vs
}
Run Code Online (Sandbox Code Playgroud)
如上所述(使用fmt.Println()),我们可以将任何至少具有 1 个返回值的函数的返回值wrap()作为其输入参数的值传递。
现在使用这个wrap()函数,看下面的例子:
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" }
Run Code Online (Sandbox Code Playgroud)
这有效,并输出(在Go Playground上尝试):
1: 1
1: 1, 2: 2
1: 1, 2: 2, 3: 3
Run Code Online (Sandbox Code Playgroud)
有关该主题的更多信息,请参阅相关问题:
不,这是不可能的.必须将多值表达式中的所有值分配给单独的变量才能使用它们,例如:
a, b := temp()
fmt.Println("first = %d and second = %d", a, b)
// first = 1 and second = 1
Run Code Online (Sandbox Code Playgroud)
[编辑]
有趣的是,在某些情况下,如果参数类型和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.
}
Run Code Online (Sandbox Code Playgroud)