Golang Range语句详解

我在学习Golang的range语句时遇到了一些困惑:

  1. range语句在遍历不同数据结构(数组、切片、map、字符串、channel)时具体有什么区别?
  2. range返回的第二个值(索引/键)在什么情况下可以忽略?
  3. 使用range遍历map时顺序是随机的吗?如何保证固定顺序遍历?
  4. 在遍历过程中修改被遍历的数据结构会有什么影响?特别是对slice和map的操作。
  5. range遍历字符串时是按字节还是按rune处理的?如何处理多字节字符?
  6. range在性能上有什么需要注意的地方?和传统的for循环相比如何? 希望有经验的开发者能帮忙解答这些疑问。
2 回复

Golang的range用于迭代数组、切片、字符串、map和通道。

  • 数组/切片:返回索引和值
  • 字符串:返回字符索引和Unicode值
  • map:返回键和值
  • 通道:迭代接收值直到关闭
    注意:range返回的是副本,修改需通过索引或指针。

更多关于Golang Range语句详解的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang 中的 range 语句用于遍历数组、切片、字符串、映射(map)或通道(channel)中的元素。它提供了一种简洁的方式来迭代这些集合类型,并返回索引(或键)和值。

基本语法

for index, value := range collection {
    // 使用 index 和 value
}
  • 对于数组、切片和字符串,index 是当前元素的索引(从 0 开始),value 是元素的值。
  • 对于映射,index 被替换为键(key),value 是对应的值。
  • 对于通道,只返回一个值(元素值),没有索引。

使用示例

1. 遍历数组或切片

nums := []int{10, 20, 30}
for i, num := range nums {
    fmt.Printf("索引: %d, 值: %d\n", i, num)
}

输出:

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

2. 遍历字符串

遍历字符串时,range 返回每个 Unicode 字符的起始字节索引和 rune 值:

str := "Go语言"
for i, ch := range str {
    fmt.Printf("索引: %d, 字符: %c\n", i, ch)
}

输出:

索引: 0, 字符: G
索引: 1, 字符: o
索引: 2, 字符: 语
索引: 5, 字符: 言

3. 遍历映射

m := map[string]int{"a": 1, "b": 2}
for key, value := range m {
    fmt.Printf("键: %s, 值: %d\n", key, value)
}

注意:映射的迭代顺序是不确定的。

4. 遍历通道

range 会从通道持续接收值,直到通道被关闭:

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

for v := range ch {
    fmt.Println(v)
}

输出:

1
2

省略索引或值

如果不需要索引或值,可以使用下划线 _ 忽略:

// 只取值
for _, num := range nums {
    fmt.Println(num)
}

// 只取索引
for i := range nums {
    fmt.Println(i)
}

注意事项

  • 遍历映射时顺序随机。
  • 字符串遍历按 rune 进行,非字节。
  • 通道遍历需确保最终关闭,否则会导致死锁。
  • 修改遍历中的集合可能导致意外行为(如映射)。

range 是 Go 中处理集合迭代的高效且简洁的方式。

回到顶部