如何理解golang多重返回值

时间:2017-09-18 04:28:01

标签: go return-value

Golang支持为多个左侧变量分配多个返回值。 E.g:

func test() (string, string) {
  return "1", "1"
}

a, b := test()

a, _ := test()

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

b = test()   //wrong

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

key, exist := map[key]

key := map[key]

我可以从这个频道读取价值

c <- myChan

c, exist <- myChan

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

2 个答案:

答案 0 :(得分:11)

golang specification中明确指出了此行为:

  1. Receive operator
  2.   

    在特殊表单

    的赋值或初始化中使用的接收表达式
    x, ok = <-ch
    x, ok := <-ch
    var x, ok = <-ch
    var x, ok T = <-ch
    
      

    产生一个额外的无类型布尔结果,报告通信是否成功。如果接收的值是通过成功的发送操作传递给通道,则ok的值为true;如果由于通道关闭且为空而产生的零值,则为false。

    1. Index expression
    2.   

      在特殊形式的赋值或初始化中使用的类型map [K] V的地图a上的索引表达式

      v, ok = a[x]
      v, ok := a[x]
      var v, ok = a[x]
      var v, ok T = a[x]
      
        

      产生一个额外的无类型布尔值。如果键x存在于映射中,则ok的值为true,否则为false。

      1. Assignments
      2.   

        元组赋值将多值运算的各个元素分配给变量列表。有两种形式。在第一个中,右手操作数是单个多值表达式,例如函数调用,通道或映射操作或类型断言。左侧的操作数数量必须与值的数量匹配。例如,如果f是一个返回两个值的函数,

        x, y = f()
        
          

        将第一个值分配给x,将第二个值分配给y。在第二种形式中,左边的操作数必须等于右边的表达式数,每个表达式必须是单值的,而右边的第n个表达式则分配给左边的第n个操作数。

        因此,您可以看到此行为是由语言设计指定的,而您无法自己实现为Receive operatorIndex expression指定的行为。

答案 1 :(得分:2)

你混淆了一个函数返回的多个值与所谓的“逗号ok”习语。

使用函数的返回值,您必须处理所有这些值,或者不处理它们。简单。

“逗号确定”更加微妙。如果您指定了第二个值,行为通常会更改。请考虑以下陈述:

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

如果x是一个包含整数的接口,那么一切都很好,但是,如果x拥有不同的类型,则第一个语句将起作用(返回0, false),第二个语句将返回http会恐慌。

具有“逗号ok”形式的每种类型的语句都是不同的特殊情况,它们与其他类型的多重赋值(例如多个函数返回值)不同。你不能用它们自己的规则来比较它们,每个都是它自己的东西。