You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何减少Go语言中两个分页DB结果迭代器的代码重复?

减少分页迭代器的代码重复:用Go泛型轻松搞定!

嘿,这个问题太典型了——当你有一堆结构几乎一模一样的迭代器时,泛型就是解决代码重复的完美方案!先瞅瞅你代码里的重复点:两个迭代器都有hasNext、app、batchSize字段,New方法和HasNext逻辑完全一致,唯一的区别就是Next里调用的查询方法和返回的模型类型。咱们用Go 1.18+支持的泛型把通用逻辑抽离出来,彻底告别重复代码!

第一步:定义通用泛型迭代器

先写一个通用的分页迭代器结构体,把所有重复的逻辑都塞进去,只把不同的部分(也就是获取分页数据的函数)作为参数传入:

// PageIterator 通用分页迭代器,T代表迭代返回的模型类型
type PageIterator[T any] struct {
    hasNext   bool
    app       *App
    batchSize int
    offset    int // 注意:原代码里offset每次重置为0是bug,这里改成结构体字段保存偏移量
    // fetchFunc 由具体模型的查询逻辑实现,用于获取指定offset和limit的分页数据
    fetchFunc func(offset, limit int) []*T
}

// NewPageIterator 创建通用分页迭代器
func NewPageIterator[T any](app *App, batchSize int, fetchFunc func(offset, limit int) []*T) *PageIterator[T] {
    return &PageIterator[T]{
        hasNext:   true,
        app:       app,
        batchSize: batchSize,
        offset:    0,
        fetchFunc: fetchFunc,
    }
}

func (it *PageIterator[T]) HasNext() bool {
    return it.hasNext
}

func (it *PageIterator[T]) Next() []*T {
    // 调用传入的查询函数获取当前页数据
    batch := it.fetchFunc(it.offset, it.batchSize)
    // 如果返回的数量小于批次大小,说明没有下一页了
    if len(batch) < it.batchSize {
        it.hasNext = false
    }
    // 偏移量累加,准备下一页查询
    it.offset += it.batchSize
    return batch
}

第二步:用通用迭代器创建具体的Foo/Bar迭代器

现在你再也不用写FooIterator和BarIterator了,只需要传入对应的查询函数就能快速创建迭代器:

// 创建Foo迭代器
fooIterator := NewPageIterator[model.Foo](a, 100, func(offset, limit int) []*model.Foo {
    return a.GetAllFoosInPages(offset, limit)
})

// 创建Bar迭代器
barIterator := NewPageIterator[model.Bar](a, 100, func(offset, limit int) []*model.Bar {
    return a.GetAllBarsInPages(offset, limit)
})

第三步:使用方式和之前完全一致

原来的循环逻辑不需要任何改动,直接用就行:

for fooIterator.HasNext() {
    fooBatch := fooIterator.Next()
    // 处理Foo数据
}

for barIterator.HasNext() {
    barBatch := barIterator.Next()
    // 处理Bar数据
}

额外提示:修复了原代码的bug

你原来的Next方法里每次都把offset初始化为0,这会导致每次都查询第一页,永远翻不了页。通用迭代器里把offset作为结构体字段保存,每次调用Next后自动累加,这才是正确的分页逻辑哦!

这个方案的好处简直拉满:

  • 完全消除了重复代码,所有通用逻辑都在PageIterator里统一维护
  • 后续新增其他模型的分页迭代器(比如Baz),只需要传对应的查询函数就行,不用再写重复的结构体和方法
  • 逻辑更清晰,把通用逻辑和具体业务逻辑彻底解耦

内容的提问来源于stack exchange,提问作者user9772923

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:08:18