登录
首页 >  Golang >  Go教程

Golangfor循环与range使用技巧

时间:2026-01-13 09:45:47 242浏览 收藏

本篇文章向大家介绍《Golang for循环与range用法详解》,主要包括,具有一定的参考价值,需要的朋友可以参考一下。

Go 只有 for 循环,无 while/do-while;它支持三段式、条件式和无限式三种写法,range 是遍历集合的语法糖,但返回值易被误读。

如何在Golang中使用循环语句_Golangfor循环和range应用

Go 语言里没有 whiledo-while,只有一种循环:for。它既承担传统 for 的角色,也覆盖了其他语言中 while 的用法;而 range 是专为遍历集合设计的语法糖,但它的行为和返回值容易被误读。

Go 的 for 有三种写法,别硬套 C 风格

很多人初学时死记“初始化;条件;后置操作”三段式,结果在需要 while 逻辑时卡住。其实 Go 的 for 更灵活:

  • for i := 0; i —— 标准三段式,适用于已知次数的迭代
  • for condition { ... } —— 纯条件循环,等价于 while;注意:没写 break 就是死循环
  • for { ... } —— 无限循环,必须靠 breakreturn 退出,常用于服务器主循环或状态轮询

错误示例:for (i = 0; i 会编译失败——Go 不支持括号包裹条件,也不允许省略分号(其实是语句分隔符,不是可选符号)。

range 遍历时下标和值的顺序不能反

range 返回两个值:索引(index)和元素(value)。但不同数据类型的第一个返回值含义不同,且一旦变量名写错顺序,就会得到意外结果:

  • 对 slice 或 array:range []int{1,2,3} → 第一个值是下标(0,1,2),第二个是值(1,2,3
  • 对 map:range map[string]int{"a":1} → 第一个值是 key("a"),第二个是 value(1);但 map 遍历无序,不能依赖顺序
  • 对 string:range "好" → 第一个值是 rune 索引(字节偏移),第二个是 rune 值('好');不是 byte 索引,所以 len("好") == 3,但 range 只走 1 次

常见错误:写成 for v, i := range s,本意想取值,结果 v 变成了下标,i 变成了值,后续逻辑全错。

range 遍历切片时,不要直接取地址存入 slice

这是 Go 新手高频踩坑点:循环中对 range 返回的 value 取地址,最后所有指针都指向同一个内存位置。

nums := []int{1, 2, 3}
var ptrs []*int
for _, v := range nums {
    ptrs = append(ptrs, &v) // ❌ 全部指向 v 的最后一轮值(3)
}
// ptrs[0], ptrs[1], ptrs[2] 解引用后全是 3

正确做法是显式创建新变量或取原 slice 的地址:

// ✅ 方案一:用索引取地址
for i := range nums {
    ptrs = append(ptrs, &nums[i])
}

// ✅ 方案二:在循环内声明新变量
for _, v := range nums {
    v := v // 创建新变量
    ptrs = append(ptrs, &v)
}

forrange 的性能与逃逸分析

大多数情况下,range 编译后和手动索引 for 性能几乎一致(Go 1.21+ 对 slice range 做了优化),但要注意几点:

  • 对小数组(如 [4]int)用 range 不会逃逸;但对大数组或未指定大小的 [...]T,可能触发栈上分配或逃逸到堆
  • for i := 0; i 时,如果 s 是函数参数,每次循环都调用 len() —— 实际上编译器会优化掉,不用手动缓存,除非你明确看到性能差异
  • map 的 range 是 O(n) 但带随机性,且期间禁止写入 map(会 panic: fatal error: concurrent map iteration and map write

真正影响性能的往往不是 for 写法本身,而是循环体内是否做了不必要的内存分配、是否触发了 GC,或者是否在循环中调用了阻塞 I/O。

以上就是《Golangfor循环与range使用技巧》的详细内容,更多关于的资料请关注golang学习网公众号!

前往漫画官网入口并下载 ➜
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>