ra

range 迭代 属于 Go

1 个练习

关于 range 迭代

在 Go 中,for range 会根据 range 表达式中的值重复执行一段代码块。 range 表达式决定每次迭代会产生一个值还是两个值。

range 表达式

遍历切片

用range遍历切片,会按顺序产生每个元素的下标和值:

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

遍历 map

用range遍历 map,会产生每个键和值,但迭代顺序无法保证。 Go 有意将 map 的迭代顺序随机化,因此同一个程序每次运行可能产生不同的输出。

hash := map[int]int{9: 10, 99: 20, 999: 30}
for k, v := range hash {
    fmt.Println(k, v)
}
// 99 20
// 999 30
// 9 10

遍历字符串

用range遍历字符串,会产生字节下标和每个 rune(Unicode 码点)。 在下面的例子中,子占三个字节,所以猫从字节下标3开始,而不是1。

for i, r := range "子猫" {
    fmt.Println(i, r, string(r))
}
// 0 23376 子
// 3 29483 猫

如果你需要的是 rune 下标,就把字符串转换成 rune 切片:

for i, r := range []rune("子猫") {
    fmt.Println(i, r, string(r))
}
// 0 23376 子
// 1 29483 猫

遍历整数

range可以直接遍历一个整数,产生的值从0开始,一直到该整数之前(不包含该整数)。 0 和负数都是合法的,但不会产生任何迭代。

for n := range 3 {
    fmt.Println(n)
}
// 0
// 1
// 2

遍历迭代器

range接受类型为iter.Seq[V]或iter.Seq2[K, V]的迭代器。 迭代器是一个函数,每次产生序列中的一个值。 range随后就可以依次遍历这些值。

text := "The quick brown fox"
for word := range strings.FieldsSeq(text) {
    fmt.Println(word)
}
// The
// quick
// brown
// fox

names := []string{"Alice", "Bob", "Vera"}
for i, v := range slices.All(names) {
    fmt.Println(i, ":", v)
}
// 0 : Alice
// 1 : Bob
// 2 : Vera

遍历 channel

最后,range可以接收通过 channel 发送的值,直到该 channel 在别处被关闭。 channel 会在后面的 track 教学大纲中更深入地讲解。

省略下标或值

在 Go 中,如果一个变量声明了却从未使用,代码就无法编译。

vals := []int{10, 20, 30}
for i, v := range vals {
    fmt.Println(v)
}
// Go build failed: declared and not used: i

如果只需要值,就把下标或键赋值给_来忽略它。

vals := []int{10, 20, 30}
for _, v := range vals {
    fmt.Println(v)
}
// 10
// 20
// 30

如果只需要下标,就完全省略它:

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

如果下标和值都不需要,两者都可以省略:

vals := []int{10, 20, 30}
count := 0
for range vals {
    count++
}
// count == 3
通过 GitHub 编辑 该链接会在新窗口或标签页中打开

学习 range 迭代