Go:范围或地图返回什么?

时间:2013-11-02 10:56:44

标签: map go range

Go具有非常简洁的多重返回值范例。但看起来v, ok := map[key]v, k := range m使用不同的机制和相同的表示法。这是一个简单的例子:

func f2() (k, v string) {
    return "Hello", "World"
}

func main(){
    k := f2() // Doesn't work : multiple-value f2() in single-value context

    m := map[string]int{"One": 1}

    // It works
    v, ok := m["One"]

    // How it all work?
    v := m["One"]
    for k := range m {}
}

在上面的示例中,k := f2()给出错误,因为f2返回两个值,而v, ok := m["One"]v := m["One"] - 两个表达式都没有任何错误。 为什么这种行为不同?

1 个答案:

答案 0 :(得分:6)

从内置map中获取,在地图,数组或切片上使用range,以及type assertions允许一个两个变量。用户定义的函数和方法不是这种情况。如果函数声明了两个返回值,则必须告诉它们如何处理它们,或者忽略它们:

k, _ := f2() // Specify what to do with each returned value
f2() // Ignoring both

为什么呢?因为规范说它是这样的:

<强> Map (indexed expressions):

  

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

     

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

     

其中索引表达式的结果是一对带有类型(V,bool)的值。在这种形式中,如果键x存在于映射中,则ok的值为true,否则为false。 v的值是单个结果形式中的值a [x]。

<强> Range (for statement):

  

对于每次迭代,迭代值的生成如下:

     

范围表达式:m map [K] V
  第一个值:键k K
  第二个值(如果存在第二个变量):m [k] V

<强> Type assertion:

  

对于接口类型的表达式x和类型T,主表达式为
  X(T)
  断言x不是nil,存储在x中的值是T类型。

  

如果在表单的赋值或初始化中使用了类型断言
  v,ok = x。(T)
  v,ok:= x。(T)
  var v,ok = x。(T)
  断言的结果是一对带有类型(T,bool)的值