如何理解golang多重返回值

Sot*_*liu 1 return-value go

Golang支持为多个左侧变量分配多个返回值.例如:

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

a, b := test()
Run Code Online (Sandbox Code Playgroud)

要么

a, _ := test()
Run Code Online (Sandbox Code Playgroud)

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

b = test()   //wrong
Run Code Online (Sandbox Code Playgroud)

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

key, exist := map[key]

key := map[key]
Run Code Online (Sandbox Code Playgroud)

我可以从这样的频道读取价值

c <- myChan

c, exist <- myChan
Run Code Online (Sandbox Code Playgroud)

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

Art*_*ger 11

golang规范中明确指出了这种行为:

  1. 接收运营商

用于特殊表单的赋值或初始化的接收表达式

x, ok = <-ch
x, ok := <-ch
var x, ok = <-ch
var x, ok T = <-ch
Run Code Online (Sandbox Code Playgroud)

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

  1. 索引表达式

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

v, ok = a[x]
v, ok := a[x]
var v, ok = a[x]
var v, ok T = a[x]
Run Code Online (Sandbox Code Playgroud)

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

  1. 分配

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

x, y = f()
Run Code Online (Sandbox Code Playgroud)

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

因此,你可以看到通过语言设计所规定的这种行为,你无法实现那些规定Receive operator和Index expression自己.