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

如何拼接Go 1.23中的两个iter.Seq[E]迭代器?

如何合并Go 1.23的iter.Seq迭代器并按顺序遍历元素?

在Go 1.23新增的iter包和range-over-func特性下,slices包确实没有提供直接合并多个iter.Seq的工具函数。要按顺序合并两个迭代器并遍历所有元素,你可以自己实现一个简单的合并函数。

实现方案

iter.Seq[V]本质是一个函数类型:type Seq[V any] func(yield func(V) bool),基于这个特性我们可以轻松实现合并逻辑:

import (
	"iter"
	"slices"
)

// concat 合并两个iter.Seq[V],先遍历第一个迭代器的所有元素,再遍历第二个
func concat[V any](a, b iter.Seq[V]) iter.Seq[V] {
	return func(yield func(V) bool) {
		// 先处理第一个迭代器
		a(yield)
		// 第一个迭代器遍历完成后,处理第二个
		b(yield)
	}
}

func main() {
	a := []int{1, 2, 3, 4}
	b := []int{5, 6, 7, 8}

	i := slices.Values(a)
	j := slices.Values(b)

	// 用range遍历合并后的迭代器
	for v := range concat(i, j) {
		println(v) // 依次输出1、2、3、4、5、6、7、8
	}
}

逻辑说明

  • concat函数返回一个新的iter.Seq[V],内部先调用第一个迭代器的函数并传入yield,等第一个迭代器的所有元素处理完毕(或中途yield返回false终止遍历),再调用第二个迭代器的函数。
  • 如果遍历过程中使用break提前终止,yield会返回false,此时第一个迭代器会停止,第二个也不会被执行,完全符合range遍历的常规行为。

扩展:合并多个迭代器

如果需要合并任意数量的iter.Seq,可以改成可变参数版本:

func concatMany[V any](seqs ...iter.Seq[V]) iter.Seq[V] {
	return func(yield func(V) bool) {
		for _, seq := range seqs {
			// 若当前迭代器遍历中途终止,直接跳出循环
			if !seq(yield) {
				break
			}
		}
	}
}

使用时可传入多个迭代器:

for v := range concatMany(i, j, slices.Values([]int{9,10})) {
	println(v)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 20:21:04