跳转到主要内容
模块 2 · 第 3 课(共 5)课程中的8/50~10 min
模块课程(3/5)

对于...范围

for ... range 是迭代集合的惯用方法: 切片、数组、映射、字符串和通道。语法略有变化 取决于集合,但基本模式始终相同: for key, value := range coll { ... }。

切片和数组的范围

返回索引和值的副本:

Go
nums := []int{10, 20, 30}
for i, v := range nums {
    fmt.Println(i, v)
}
// 0 10
// 1 20
// 2 30

通常两者之一就足够了:

Go
// solo indice
for i := range nums { _ = i }

// solo valore (ignora indice con _)
for _, v := range nums { _ = v }

地图上的范围

返回键和值:

Go
prices := map[string]int{"pane": 2, "latte": 3, "vino": 8}
for k, v := range prices {
    fmt.Println(k, v)
}

字符串的范围:符文,而不是字节

for i, r := range s 迭代 每个 Unicode 代码点(符文),而不是每个 字节。索引 i 是符文开头的字节偏移量。

Go
for i, r := range "èé" {
    fmt.Printf("%d %c (%U)\n", i, r, r)
}
// 0 è (U+00E8)
// 2 é (U+00E9)

要迭代每个字节,请使用经典索引:

Go
s := "ciao"
for i := 0; i < len(s); i++ {
    fmt.Println(s[i])  // byte (uint8)
}

通道上的范围

迭代直到通道关闭:

Go
ch := make(chan int)
go func() {
    for i := 0; i < 3; i++ { ch <- i }
    close(ch)
}()
for v := range ch {
    fmt.Println(v)
}

我们将深入研究并发模块。

尝试一下

锻炼#go.m2.l3.e1
尝试:0加载中...

使用 for-range 打印 nums 每个元素的索引和值。

正在加载编辑器...

3 次尝试后可用的解决方案

锻炼#go.m2.l3.e2
尝试:0加载中...

将忽略索引的所有 nums 值求和到总计中。

正在加载编辑器...
显示提示

使用“_”放弃索引。

3 次尝试后可用的解决方案

Quiz#go.m2.l3.e3
准备好

当 m 是映射时,“for k, v := range m”中的第一个变量代表什么?

Go
m := map[string]int{"a": 1, "b": 2}
for k, v := range m { fmt.Println(k, v) }
答案选项

回顾

  • for k, v := range coll 具有明确的范围:使用 _ 丢弃不使用的内容。
  • 切片/数组:索引+值的副本。变异,索引。
  • 地图:键+值,每次运行时顺序随机。
  • 字符串:范围按符文(代码点)迭代,而不是按字节迭代。
  • Channel:在通道打开时迭代;以 close() 关闭。