目录

  1. 什么是 range
  2. range 用法
  3. range 的返回值
  4. 使用 range 的技巧
  5. 总结

什么是 range

range 是 Go 语言中的一个关键字,用于遍历数组、切片、字符串、映射(map)和通道(channel)。range 在循环中常用于获取容器中的元素和值,并且能方便地进行迭代操作。它不仅能简化代码,还能提高代码的可读性和效率。

range 用法

遍历数组

在 Go 语言中,range 可以用来遍历数组的索引和值。对于数组的每次迭代,range 会返回索引和对应的值。

arr := [3]int{1, 2, 3}
for index, value := range arr {
    fmt.Println("索引:", index, "值:", value)
}

输出:

索引: 0 值: 1
索引: 1 值: 2
索引: 2 值: 3

遍历切片

range 也可以用于遍历切片,和数组类似,返回索引和值。由于切片长度可以动态变化,range 会根据切片的当前长度进行遍历。

slice := []int{10, 20, 30}
for index, value := range slice {
    fmt.Println("索引:", index, "值:", value)
}

输出:

索引: 0 值: 10
索引: 1 值: 20
索引: 2 值: 30

遍历字符串

range 可以用于遍历字符串,返回的是 Unicode 字符的索引和字符(按 Unicode 编码值表示)。

str := "Hello"
for index, runeValue := range str {
    fmt.Printf("字符位置: %d, 字符: %c\n", index, runeValue)
}

输出:

字符位置: 0, 字符: H
字符位置: 1, 字符: e
字符位置: 2, 字符: l
字符位置: 3, 字符: l
字符位置: 4, 字符: o

遍历映射(map)

range 还可以用于遍历映射(map)。对于每个元素,range 返回键和值。

m := map[string]int{"a": 1, "b": 2, "c": 3}
for key, value := range m {
    fmt.Println("键:", key, "值:", value)
}

输出:

键: a 值: 1
键: b 值: 2
键: c 值: 3

注意,遍历映射时,range 返回的顺序是不确定的,因为 Go 中的映射是无序的。

遍历通道(channel)

range 还可以用于遍历通道(channel)。当通道关闭时,range 会自动停止遍历。

ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)

for value := range ch {
    fmt.Println("接收到的值:", value)
}

输出:

接收到的值: 1
接收到的值: 2
接收到的值: 3

在上述示例中,range 会从通道中接收数据,直到通道关闭并且没有更多数据时停止。

range 的返回值

range 在迭代容器时会返回两个值:索引(或者键)和值。你可以根据需要选择忽略某一个值。

忽略索引(或键)

如果你只关心元素的值,可以忽略索引(或键)。通过使用 _ 来丢弃该值:

arr := [3]int{1, 2, 3}
for _, value := range arr {
    fmt.Println("值:", value)
}

输出:

值: 1
值: 2
值: 3

忽略值

如果只关心索引(或键),可以忽略值:

m := map[string]int{"a": 1, "b": 2, "c": 3}
for key, _ := range m {
    fmt.Println("键:", key)
}

输出:

键: a
键: b
键: c

使用 range 的技巧

遍历数组或切片时使用 range 来修改元素

虽然 range 返回的是元素的副本,但如果需要修改原始数组或切片的元素,可以通过索引直接访问并修改:

arr := []int{1, 2, 3}
for i := range arr {
    arr[i] *= 2  // 修改原数组的元素
}
fmt.Println(arr)  // 输出 [2, 4, 6]

遍历并求和

range 也常用于对切片或数组进行求和等聚合操作:

nums := []int{1, 2, 3, 4, 5}
sum := 0
for _, value := range nums {
    sum += value
}
fmt.Println("总和:", sum)  // 输出 15

遍历映射时保留键的顺序

虽然 range 遍历映射时顺序不确定,如果需要保证顺序,可以将键值对存储到切片中,排序后再遍历:

m := map[string]int{"a": 1, "c": 3, "b": 2}
keys := []string{}
for key := range m {
    keys = append(keys, key)
}
sort.Strings(keys)  // 排序键

for _, key := range keys {
    fmt.Println("键:", key, "值:", m[key])
}

总结

range 是 Go 语言中非常有用的关键字,提供了一种简洁且高效的方式来遍历数组、切片、字符串、映射和通道。它能够帮助开发者快速迭代数据结构,并且在处理大规模数据时效率较高。理解并掌握 range 的用法,能够让你在开发中更加高效和灵活。

参考资料

  1. Go 官方文档 – range
  2. Go 语言 range 语法详解
  3. Go range 的使用详解

这篇文章详细介绍了 Go 语言中的 range 关键字及其使用方法,帮助你更好地理解和使用这个强大的工具。