为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
明月笑刀无情 2023-04-17 16:13:12
我有一个返回两个整数值的 Go 函数。下面是函数func temp() (int, int){ return 1,1}是否可以将temp函数直接放入 aPrintln并使用如下字符串格式打印两个输出:fmt.Println("first= %d and second = %d", temp() ) // This doesn't work在 Python 中,我能够执行以下操作:def func():    return 1,1print("{0}={1}".format(*func())>> '1=2'我也可以在 Go 中做类似的事情吗?
查看完整描述

3 回答

?
慕的地8271018

TA贡献1796条经验 获得超4个赞

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

展望未来,这在默认情况下不受支持,因为引用自Spec: Calls:

作为一种特殊情况,如果一个函数或方法的返回值g在数量上相等并且可以单独分配给另一个函数或方法的参数f,那么调用将在按顺序将返回值绑定到参数后f(g(parameters_of_g))调用。除了 的调用之外,的调用不得包含任何参数,并且必须至少有一个返回值。如果有一个最终参数,它会被分配常规参数分配后剩余的返回值。fgffggf...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: %v\n", 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: %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" }

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


1: 1

1: 1, 2: 2

1: 1, 2: 2, 3: 3


查看完整回答
反对 回复 2023-04-17
?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

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


a, b := temp()

fmt.Println("first = %d and second = %d", a, b)

// first = 1 and second = 1

[编辑]


有趣的是,在某些情况下,如果参数类型和元数匹配,或者对于纯可变参数函数( 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.

}



查看完整回答
反对 回复 2023-04-17
?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

当我没有使用任何字符串格式时,我能够打印它,如下所示

fmt.Println(temp())

这仅由 支持Println,但不支持printf


查看完整回答
反对 回复 2023-04-17
  • 3 回答
  • 0 关注
  • 170 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信