如何拼接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
相关产品推荐
相关产品推荐

