3 回答
TA贡献1796条经验 获得超4个赞
首先,对于您尝试做的事情,您应该使用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)
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
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.
}
- 3 回答
- 0 关注
- 170 浏览
添加回答
举报