如何将多个返回值传递给可变参数函数?



我有一个返回两个整数值的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的参数后调用ff的调用不能包含除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

相关内容

  • 没有找到相关文章

最新更新