我有一个返回两个整数值的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'
我也可以在 Go 中做类似的事情吗?
前言:我在github.com/icza/gox
年发布了这个实用程序,见gox.Wrap()
。
首先,对于您尝试执行的操作,您应该使用fmt.Printf()
而不是fmt.Println()
,因为只有前者期望并使用格式字符串。
展望未来,默认情况下不支持此功能,因为引用 Spec: 调用:
作为特殊情况,如果一个函数或方法
g
的返回值数量相等,并且可以单独分配给另一个函数或方法的参数f
,则调用f(g(parameters_of_g))
将在将g
的返回值按顺序绑定到f
的参数后调用f
。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{}
的值,我们可以使用...
将其作为某个可变参数的值传递。
意思是这有效:
func main() {
fmt.Printf("1: %v, 2: %vn", temp()...)
}
func temp() []interface{} { return []interface{}{1, 2} }
它可以正确打印(在Go Playground上尝试(:
1: 1, 2: 2
所以我们只需要一个实用程序函数,它将任何函数的返回值包装到[]interface{}
中,因此我们可以使用它传递给fmt.Printf()
。
这很简单:
func wrap(vs ...interface{}) []interface{} {
return vs
}
如上所述(使用fmt.Println()
(,我们可以将任何至少具有 1 个返回值的函数的返回值传递给wrap()
作为其输入参数的值。
现在使用此wrap()
函数,请参阅以下示例:
func main() {
fmt.Printf("1: %vn", wrap(oneInt())...)
fmt.Printf("1: %v, 2: %vn", wrap(twoInts())...)
fmt.Printf("1: %v, 2: %v, 3: %vn", wrap(threeStrings())...)
}
func oneInt() int { return 1 }
func twoInts() (int, int) { return 1, 2 }
func threeStrings() (string, string, string) { return "1", "2", "3" }
这有效,并且输出(在Go Playground上尝试(:
1: 1
1: 1, 2: 2
1: 1, 2: 2, 3: 3
有关该主题的更多信息,请参阅相关问题:
单值上下文中的多个值
在正常函数上返回像 Golang 中的"ok"这样的映射
不,这是不可能的。 您必须将多值表达式中的所有值分配给单独的变量才能使用它们,例如:
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.
}
当我不使用任何字符串格式时,我能够打印它,如下所示
fmt.Println(temp())
这只得到了Println
的支持,但没有得到printf