慕的地8271018
首先,对于您尝试做的事情,您应该使用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: 11: 1, 2: 21: 1, 2: 2, 3: 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.}