Go 语言范围(Range)
range 是 Go 语言中的一个关键字,用于在 for 循环中迭代数组、切片、映射(map)、通道(channel)等数据结构。range 提供了简便且高效的方式来遍历这些数据结构,并且它在性能上优于手动索引。
1. 使用 range 遍历数组和切片
当 range 用于数组或切片时,它返回两个值:
- 索引(index):当前元素的索引。
- 值(value):当前索引位置的元素值。
1.1 示例:遍历数组
arr := [3]int{1, 2, 3}
for index, value := range arr {
fmt.Println("Index:", index, "Value:", value)
}
输出:
Index: 0 Value: 1
Index: 1 Value: 2
Index: 2 Value: 3
1.2 示例:遍历切片
slice := []int{10, 20, 30}
for index, value := range slice {
fmt.Println("Index:", index, "Value:", value)
}
输出:
Index: 0 Value: 10
Index: 1 Value: 20
Index: 2 Value: 30
2. 只使用索引或只使用值
如果你不需要索引或值中的任何一个,你可以用下划线 _ 来忽略它。
2.1 只获取值
arr := [3]int{1, 2, 3}
for _, value := range arr {
fmt.Println("Value:", value)
}
输出:
Value: 1
Value: 2
Value: 3
2.2 只获取索引
slice := []int{10, 20, 30}
for index, _ := range slice {
fmt.Println("Index:", index)
}
输出:
Index: 0
Index: 1
Index: 2
3. 使用 range 遍历映射(Map)
当 range 用于映射时,它返回两个值:
- 键(key):当前元素的键。
- 值(value):当前键对应的值。
3.1 示例:遍历映射
m := map[string]int{"a": 1, "b": 2, "c": 3}
for key, value := range m {
fmt.Println("Key:", key, "Value:", value)
}
输出:
Key: a Value: 1
Key: b Value: 2
Key: c Value: 3
在 Go 语言中,映射的遍历顺序是不确定的,因此每次执行时,键值对的顺序可能不同。
3.2 只获取键或值
m := map[string]int{"a": 1, "b": 2}
for key := range m {
fmt.Println("Key:", key)
}
for _, value := range m {
fmt.Println("Value:", value)
}
4. 使用 range 遍历通道(Channel)
当 range 用于通道时,它返回通道中的每个元素。你可以使用 range 循环从通道中接收数据,直到通道关闭。
4.1 示例:遍历通道
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)
for value := range ch {
fmt.Println("Received:", value)
}
输出:
Received: 1
Received: 2
Received: 3
range 在遍历通道时会在通道关闭时自动退出循环。
5. 性能和最佳实践
- 数组和切片:
range的性能是相当高效的,它会自动处理索引和复制值(通过传值或引用)。 - 映射(Map):
range适合用于遍历映射,但请注意遍历顺序不稳定。 - 通道(Channel):
range是处理通道的推荐方式,尤其是当通道关闭时,它可以确保所有数据都被接收。
6. 总结
range是 Go 语言中一个非常有用的工具,能简化迭代操作并提高代码可读性。range可以用于数组、切片、映射和通道等数据结构。- 使用
range时,你可以选择同时获取索引和元素值,或只获取其中一个。 range在处理通道时,能够自动处理通道关闭。