电话
400 9058 355
Go 1.22 的 range 迭代器是 range 语句对函数返回迭代器的扩展,要求函数返回 func() (T, bool) 类型;编译器自动展开为循环,适用于懒加载、分页等场景。
Go 1.22 引入的 range 函数迭代器(即支持对函数返回的迭代器进行 range)不是新语法,而是语言对 range 语句的扩展:只要函数返回符合迭代器协议的类型(两个返回值:元素、布尔值),就能直接用 range 遍历。它让业务代码更简洁、更声明式,尤其适合懒加载、分页、流式处理等场景。
核心是返回一个函数,该函数每次调用返回 value, ok —— 类似 map 或 channel 的迭代行为。Go 编译器会自动识别并展开为循环。
例如,实现一个从数据库分批拉取用户 ID 的迭代器:
func UserIDsIterator(db *sql.DB, batchSize int) func() (int64, bool) {
rows := make(chan int64, batchSize)
go func() {
defer close(rows)
offset := 0
for {

var ids []int64
err := db.Select(&ids, "SELECT id FROM users ORDER BY id LIMIT ? OFFSET ?", batchSize, offset)
if err != nil || len(ids) == 0 {
return
}
for _, id := range ids {
rows <- id
}
offset += batchSize
}
}()
return func() (int64, bool) {
id, ok := <-rows
return id, ok
}
}使用时直接 range:
for id := range UserIDsIterator(db, 100) {
// 处理单个用户 ID
processUser(id)
}迭代器函数内部需自行管理状态(如游标、缓冲、关闭逻辑)。若涉及 goroutine + channel,注意资源泄漏和 panic 传播。
i),应捕获副本把通用逻辑封装成可组合的迭代器,提升复用性:
// 分页包装器
func Paginate[T any](fetcher func(offset, limit int) ([]T, error), limit int) func() (T, bool) {
offset := 0
var cache []T
var cacheIdx int
return func() (T, bool) {
if cacheIdx >= len(cache) {
cache, _ = fetcher(offset, limit)
if len(cache) == 0 {
var zero T
return zero, false
}
cacheIdx = 0
offset += limit
}
v := cache[cacheIdx]
cacheIdx++
return v, true
}
}
// 使用:遍历所有订单(自动分页)
for order := range Paginate(db.FetchOrders, 50) {
sendNotification(order)
}
不是所有场景都适合。简单切片、已知长度集合、性能敏感内层循环,仍优先用传统 for i := range 或 for _, v := range。
break 后继续(除非自己维护状态)ok,不暴露错误详情;需在迭代器内部记录日志或 panic
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...