首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Go语言中的for-range不只是遍历slice和map

Go语言中的for-range不只是遍历slice和map

作者头像
技术圈
发布2026-03-02 20:08:27
发布2026-03-02 20:08:27
790
举报

在 Go 语言开发中,for range 是最常用的遍历语法之一。很多开发者可能只知道它可以用来遍历切片(slice)和映射(map),但实际上 for range 的能力远不止于此。

常见用法

1. 遍历切片(Slice)

遍历切片是 for range 最常见的用法之一,它会返回索引和元素值:

代码语言:javascript
复制
slice := []string{"Go", "Python", "Java"}
for index, value := range slice {
    fmt.Printf("索引: %d, 值: %s\n", index, value)
}
// 输出:
// 索引: 0, 值: Go
// 索引: 1, 值: Python
// 索引: 2, 值: Java

2. 遍历映射(Map)

遍历映射同样常用,它会返回键和值:

代码语言:javascript
复制
m := map[string]int{"a": 1, "b": 2, "c": 3}
for key, value := range m {
    fmt.Printf("键: %s, 值: %d\n", key, value)
}
// 可能的输出(顺序随机):
// 键: a, 值: 1
// 键: b, 值: 2
// 键: c, 值: 3

注意:map 的遍历顺序是随机的,每次运行可能不同。

你可能不知道的用法

除了切片和映射,for range 还支持遍历以下三种类型,这些用法在实际开发中同样非常有用。

1. 遍历数组(Array)

遍历数组的语法与切片相同,返回索引和元素值:

代码语言:javascript
复制
array := [3]int{1, 2, 3}
for i, v := range array {
    fmt.Printf("索引: %d, 值: %d\n", i, v)
}
// 输出:
// 索引: 0, 值: 1
// 索引: 1, 值: 2
// 索引: 2, 值: 3

注意:遍历数组时,返回的元素值是数组元素的副本,修改该值不会影响原数组。

2. 遍历字符串(String)

这是一个非常实用但容易被忽略的特性。遍历字符串时,for range 会返回字符的索引和对应的 Unicode 码点(rune):

代码语言:javascript
复制
str := "Hello 世界"
for index, char := range str {
    fmt.Printf("索引: %d, 字符: %c\n", index, char)
}
// 输出:
// 索引: 0, 字符: H
// 索引: 1, 字符: e
// 索引: 2, 字符: l
// 索引: 3, 字符: l
// 索引: 4, 字符: o
// 索引: 5, 字符:  
// 索引: 6, 字符: 世
// 索引: 9, 字符: 界

重要特性

  • 字符串遍历会自动处理 Unicode 字符,每个中文字符占 3 个字节,但会被视为一个完整的 rune。
  • 索引值是字符的起始字节位置,不是字符的序号。

这个特性在处理包含中文、emoji 等多字节字符的字符串时特别有用,避免了手动处理 UTF-8 编码的麻烦。

3. 遍历通道(Channel)

这是一个非常优雅的特性。遍历通道时,for range 会持续从通道接收值,直到通道被关闭:

代码语言:javascript
复制
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)

for value := range ch {
    fmt.Println("从通道接收:", value)
}
// 输出:
// 从通道接收: 1
// 从通道接收: 2
// 从通道接收: 3

重要特性

  • 如果通道未关闭,for range 会一直阻塞等待新值。
  • 遍历通道时,只返回通道中的值,没有索引。
  • 当通道关闭后,for range 会自动退出循环。

这种写法比传统的 for-select 模式更加简洁,是处理通道数据的推荐方式。

for range 的特殊用法

1. 只需要索引

可以使用下划线 _ 忽略值:

代码语言:javascript
复制
for i := range slice {
    fmt.Println("索引:", i)
}

2. 只需要值

可以省略索引变量:

代码语言:javascript
复制
for _, v := range slice {
    fmt.Println("值:", v)
}

3. 仅遍历次数

对于数组或切片,也可以直接遍历而不使用索引和值,用于执行固定次数的循环:

代码语言:javascript
复制
for range slice {
    fmt.Println("执行一次")
}

注意事项

遍历副本问题

当遍历数组、切片或字符串时,for range 返回的元素值是副本,修改该值不会影响原数据。如果需要修改原数据,应使用索引访问。

Map 遍历顺序问题

Map 的遍历顺序是随机的,不要依赖遍历顺序。如果需要固定顺序,应先将键排序,再按排序后的键访问。

通道阻塞问题

如果通道未关闭,for range 会一直阻塞等待新值。确保在发送完所有数据后关闭通道,避免程序卡死。

遍历过程中修改集合

在遍历 map 时,如果添加或删除元素,可能会影响遍历结果。虽然 Go 语言允许在遍历过程中修改 map,但行为是不确定的,建议避免这种做法。

写在最后

for range 是 Go 语言中一个功能强大的遍历工具,它不仅支持遍历切片和映射,还支持遍历数组、字符串和通道。每种类型都有其独特的特性:

类型

返回值

特性

数组

索引、元素值

元素是副本

切片

索引、元素值

元素是副本

字符串

索引、rune

自动处理 Unicode

映射

键、值

遍历顺序随机

通道

阻塞直到关闭

在实际开发中,建议根据具体需求选择合适的遍历方式。对于字符串处理,for range 的 Unicode 支持是一个很大的优势;对于通道遍历,for range 提供了最优雅的解决方案。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-02-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 技术圈子 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 常见用法
    • 1. 遍历切片(Slice)
    • 2. 遍历映射(Map)
  • 你可能不知道的用法
    • 1. 遍历数组(Array)
    • 2. 遍历字符串(String)
    • 3. 遍历通道(Channel)
  • for range 的特殊用法
    • 1. 只需要索引
    • 2. 只需要值
    • 3. 仅遍历次数
  • 注意事项
    • 遍历副本问题
    • Map 遍历顺序问题
    • 通道阻塞问题
    • 遍历过程中修改集合
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档