Go如何确定可以使用多个值的上下文?

时间:2019-01-29 15:36:51

标签: go types error-handling return-value multiple-return-values

package main

import "fmt"

func multipleRets() (int, int, int, int) {
    return 11, 22, 33, 44
}

func main() {
    // Q1
    fmt.Println(multipleRets())    // This is fine.
    fmt.Println(1, multipleRets()) // But this one errors.

    // Q2
    s1 := append([]int{}, []int{11, 22, 33, 44}...) // This is fine.
    s2 := append([]int{}, multipleRets())           // But this one errors.

    // Q3
    lit1 := []int{11, 22, 33, 44} // This is fine.
    lit2 := []int{multipleRets()} // But this one errors.

    // Q4
    fmt.Println(1, []int{11, 22, 33, 44})    // This is fine.
    fmt.Println(1, []int{11, 22, 33, 44}...) // But this one errors.
}

上面的源代码中有4个错误,所有这些都抱怨多个元素不能放在一个函数/文字中。

但是在我想到其他示例时,我无法真正找到将这些错误视为错误的原因。

他们应该没事吗?当Go发出类似“单值上下文中的多值”这样的错误时,这是​​什么意思?

那三个有害点的工作方式如何? ...到底是做什么的?

1 个答案:

答案 0 :(得分:4)

这就是Go设计师避免使用语法糖的原因;当您期望糖过多时,它会导致混乱。您在此处的Go中看到了两种类型的语法糖:爆炸切片传递给一个可变参数函数,并传递多个返回值的函数。

将切片分解为可变参数的功能在此处记录:https://golang.org/ref/spec#Passing_arguments_to_..._parameters,关键细节为:

  

如果最后一个参数是分配给一个片类型[] T,它可以当参数之后传递不变作为a的值... T参数....在这种情况下不创建新切片

fmt.Println是一个单一的,可变参数的参数的函数。这意味着你可以通过它的个别项目,或单个项目这是一个声明切片与...爆炸所附操作者,在这种情况下该切片将被传递不变。它不能是一个切片文字,并且它不能跟随其它参数,以便利用这个辅助函数。

在其它记录在这里:https://golang.org/ref/spec#Calls具体是:

  

在一个特殊情况下,如果一个函数或方法g的返回值数量相等并且可以分别分配给另一个函数或方法f的参数,则调用f(g(parameters_of_g))将在绑定后调用f g的返回值到f的参数顺序。 f的调用除g的调用外不得包含任何参数,并且g至少应具有一个返回值。如果f具有最终...参数,它被分配的是保持定期参数的分配后克的返回值。

同样,因为fmt.Println具有单个可变参数,所以不能使用上述语法糖来混合和匹配传递的特定值,而将语法直接传递给另一个函数的参数使用多值返回。

正如Peter笔记“和Q3是一个切片的文本,这不支持可变参数‘参数’在所有(因为这些值不参数)”。上面用于将多个返回值传递给函数的语法糖仅由于根本不是函数而不适用于切片文字。