Go 中有 foreach 吗?包含示例的逐步教程
\n\n如果您是从 Python、JavaScript 或 PHP 转到 Go,那么您一定习惯了简洁的 foreach 来遍历集合。现在您编写第一个 Go 循环时会问自己:“我钟爱的 foreach 在哪里?Go 中难道没有它吗?”
剧透:Go 中确实没有直接的 foreach 关键字。但有一种更灵活、更强大的东西——for range 结构。在本教程中,我们将分析 Go 中的迭代是如何工作的,展示真实的代码示例,并将其与您在其他语言中熟悉的 foreach 进行比较。
为什么 Go 中没有 foreach 以及为什么需要 range?
\n\nGo 是一种极简语言。其创建者有意避免语法结构的重复。他们没有添加单独的 foreach 关键字,而是扩展了现有 for 循环的功能。于是诞生了 for range——一个用于遍历数组、切片(slices)、映射(maps)、字符串甚至通道(channels)的通用工具。
如果您正在 Go 中寻找 foreach 的精确替代,那么它就是 for range。
for range 语法:通俗易懂的解析
\n\n基本结构如下:
\n\nfor index, value := range collection {\n // 循环体\n}\n\n其中:
\n- \n
index— 元素的索引(对于数组和切片)或键(对于映射)。 \n value— 元素值的副本。 \n collection— 您的集合(切片、数组、map、字符串或通道)。 \n
重要提示:value 始终是元素的副本。如果您在循环内修改 value,原始元素不会改变。要修改原始元素,需要通过索引访问。
示例 1:遍历切片(slice)——Go 中 foreach 的替代
\n\n我们从最常见的情况开始——遍历切片元素:
\n\npackage main\n\nimport "fmt"\n\nfunc main() {\n fruits := []string{"苹果", "香蕉", "樱桃", "甜瓜"}\n\n fmt.Println("遍历切片(foreach 替代):")\n for index, fruit := range fruits {\n fmt.Printf("索引 %d: %s\\n", index, fruit)\n }\n}\n\n输出:
\n遍历切片(foreach 替代):\n索引 0: 苹果\n索引 1: 香蕉\n索引 2: 樱桃\n索引 3: 甜瓜\n\n如果您只需要索引(例如,为了修改元素),可以省略值:
\n\nfor i := range fruits {\n fruits[i] = "水果: " + fruits[i]\n}\n\n如果只需要值——请使用下划线 _:
for _, fruit := range fruits {\n fmt.Println(fruit)\n}\n\n示例 2:遍历 map——经典的 foreach
\n\n在 Go 中,没有比 for range 更优雅的遍历映射的方式了:
package main\n\nimport "fmt"\n\nfunc main() {\n ages := map[string]int{\n "安娜": 25,\n "鲍里斯": 30,\n "维克多": 35,\n }\n\n fmt.Println("遍历 map(foreach):")\n for name, age := range ages {\n fmt.Printf("%s: %d 岁\\n", name, age)\n }\n}\n\nGo 中 map 的遍历顺序不保证。如果您需要稳定的顺序,请将键收集到切片中并对其进行排序。
\n\n示例 3:遍历字符串——按字符迭代
\n\n与许多语言不同,Go 中的 for range 按符文(unicode 字符)迭代,而不是按字节:
package main\n\nimport "fmt"\n\nfunc main() {\n text := "你好,Go!"\n\n fmt.Println("按字符遍历字符串:")\n for i, r := range text {\n fmt.Printf("位置 %d: 字符 '%c' (代码 %U)\\n", i, r, r)\n }\n}\n\n请注意:索引 i 指向符文的起始字节,而不是字符的序号。对于单字节字符串