Go 语言 Range 范围迭代

forrangeforEachrange

数组 / 切片

rangerange
  • 不关心索引与元素
  • 遍历获取索引
  • 遍历获取索引与对应元素
package main

import "fmt"

func main() {
    s := []int{1, 2, 3,}
    for range s {
        fmt.Println(s)
    }
    for idx := range s {
        fmt.Println("idx:", idx)
    }
    for idx, elem := range s {
        fmt.Println("idx:", idx, "elem:", elem)
    }
}
代码示例:Go 数组/切片 Range 范围迭代

字符串

rangerune
package main

import "fmt"

func main() {
    s := "Golang"
    for range s {
        fmt.Println(s)
    }
    for idx := range s {
        fmt.Println("idx:", idx)
    }
    for idx, r := range s {
        fmt.Println("idx:", idx, "rune:", r)
    }
}
代码示例:Go 字符串 Range 范围迭代

哈希表

maprange
  • 不关心键与值
  • 遍历获取键
  • 遍历获取键与对应值

需要注意的是,Go 哈希表遍历是无序的,Go 团队在设计哈希表的遍历操作时特意引入了随机数以保证遍历的随机性,也是为了告诉 Go 程序员,程序不要依赖于哈希表的有序遍历。

package main

import "fmt"

func main() {
    m := map[string]string{
        "k1": "v1",
        "k2": "v2",
        "k3": "v3",
    }
    for range m {
        fmt.Println(m)
    }
    for k := range m {
        fmt.Println("key:", k)
    }
    for k, v := range m {
        fmt.Println("key:", k, "value", v)
    }
}
代码示例:Go 哈希表 Range 范围迭代

通道

rangefor v := range ch {}for<-chhbhv
// for v := range ch {}
for hv, hb := <-ch; hb; hv, hb = <-ch {
    // ...
}
代码示例:Go 通道 Range 范围迭代等价转换

Go 范围迭代注意事项

range
  • 迭代变量均为值拷贝
  • 数组/切片的范围迭代在编译时刻就已确定。
  • 迭代时修改迭代对象会发生不可预期行为

参考资料

  • A Tour of Go
  • Go 语言设计与实现:https://draveness.me/golang/docs/part2-foundation/ch05-keyword/golang-for-range