【问题标题】:Iteration order of `for ... range` when the index is implicit隐式索引时`for ... range`的迭代顺序
【发布时间】:2019-06-27 23:36:36
【问题描述】:

https://golang.org/ref/spec#For_range

对于带有 range 子句的语句

对于数组、指向数组的指针或切片值 a,索引迭代值按递增顺序生成,从元素索引 0 开始。如果最多存在一个迭代变量,则范围循环从 0 开始生成迭代值到 len(a)-1 并且不索引到数组或切片本身。对于 nil 切片,迭代次数为 0。

根据规范,在 Go 中迭代线性数据结构(数组或切片或字符串)将始终按照索引增加的顺序获取其中的每个元素。

for i, v := range []int{11, 22, 33, 44} {
    fmt.Println(i, v)
}

但问题是,我在规范中找不到真正的保证,

这个带有隐式索引迭代值的 range-iterate-over 子句也将始终保持相同的顺序:

for _, v := range []int{11, 22, 33, 44} {
    fmt.Println(v)
}

我上面放的这两个例子会总是以相同的顺序执行吗?

我认为他们会这样做,但我还没有听到承诺。

当索引迭代值由空白标识符(下划线_)表示时,for ... range如何工作?

【问题讨论】:

  • 完全一样。唯一的区别是您没有将索引分配给变量。
  • 有什么证据吗?我知道他们是一样的。如果我写了后者,而就在有一天程序突然开始以随机顺序检索元素,就好像切片是一张地图一样,会发生什么?我想确定没有索引的for ... range 是否真的可靠。
  • 证明在规范中。如果它做除此之外的任何事情,它就坏了。 blank identifier 只是一个标识符。根据定义,它不能产生任何其他影响。

标签: for-loop go slice specifications


【解决方案1】:

它在规范中,但我认为你忽略了一些东西。有迭代值和迭代变量。

对于每个条目,它会将迭代值分配给相应的迭代变量(如果存在),然后执行该块。

您的报价指的是迭代值:

对于数组、指向数组的指针或切片值a,索引迭代值按递增顺序生成,从元素索引 0 开始。如果最多存在一个迭代变量, range 循环产生从 0 到 len(a)-1 的迭代值,并且不索引到数组或切片本身。

如您所见,无论有多少迭代变量,迭代值总是按递增顺序排列,从元素索引 0 开始。

而第二次迭代值始终为a[i],其中i对应第一次迭代值,索引:

Range expression                          1st value          2nd value

array or slice  a  [n]E, *[n]E, or []E    index    i  int    a[i]       E

【讨论】:

    猜你喜欢
    • 2016-04-21
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-08
    • 1970-01-01
    • 2018-05-31
    • 1970-01-01
    相关资源
    最近更新 更多