Golang支持将多个返回值分配给多个左侧变量。 例如:

1
2
3
4
5
func test() (string, string) {
  return"1","1"
}

a, b := test()

要么

1
a, _ := test()

并且接收变量和返回值的数量必须匹配:

1
b = test()   //wrong

但是对于某些内置类型,例如[]或<-,支持可变数量的返回值

1
2
3
key, exist := map[key]

key := map[key]

我可以这样从渠道中读取价值

1
2
3
c <- myChan

c, exist <- myChan

我们如何解释不一致之处? 这是保留给核心运行时/语言的功能吗?

  • 您基本上是在问:为什么Go实施语言规范?
  • 正常功能在Golang中可能与Return map相同,例如ok。

在golang规范中明确指定了以下行为:

  • 接收运算符
  • A receive expression used in an assignment or initialization of the special form

    1
    2
    3
    4
    x, ok = <-ch
    x, ok := <-ch
    var x, ok = <-ch
    var x, ok T = <-ch

    yields an additional untyped boolean result reporting whether the communication succeeded. The value of ok is true if the value received was delivered by a successful send operation to the channel, or false if it is a zero value generated because the channel is closed and empty.

  • 索引表达
  • An index expression on a map a of type map[K]V used in an assignment or initialization of the special form

    1
    2
    3
    4
    v, ok = a[x]
    v, ok := a[x]
    var v, ok = a[x]
    var v, ok T = a[x]

    yields an additional untyped boolean value. The value of ok is true if the key x is present in the map, and false otherwise.

  • 作业
  • A tuple assignment assigns the individual elements of a multi-valued operation to a list of variables. There are two forms. In the first, the right hand operand is a single multi-valued expression such as a function call, a channel or map operation, or a type assertion. The number of operands on the left hand side must match the number of values. For instance, if f is a function returning two values,

    1
    x, y = f()

    assigns the first value to x and the second to y. In the second form, the number of operands on the left must equal the number of expressions on the right, each of which must be single-valued, and the nth expression on the right is assigned to the nth operand on the left.

    因此,如您所见,这种行为是由语言设计指定的,您无法自己实现为Receive operatorIndex expression指定的行为。


    您将函数返回的多个值与所谓的"逗号好"成语相混淆。

    使用函数的返回值,您必须要么全部处理要么都不处理。简单。

    "逗号确定"更为微妙。如果您指定了第二个值,则通常会更改行为。考虑以下语句:

    1
    2
    3
    v, ok := x.(int)
    // vs
    v := x.(int)

    如果x是一个保存整数的接口,那么一切都很好,但是,如果x拥有不同的类型,则第一个语句将起作用(返回0, false),第二个语句将出现紧急情况。

    每种形式以"逗号ok"形式的语句都是不同的特殊情况,它们与其他类型的多个赋值(例如,多个函数返回值)不同。您无法将它们进行比较,每个都是它自己的东西,都有自己的规则。