range迭代器实现
在 Go 中实现迭代器函数是处理大型数据集或流式数据的核心技能。
迭代器三要素
状态保持:记录当前迭代位置
值生成:按需产生下一个值
终止条件:检测迭代结束
实现方式对比
实现方式
优点
缺点
适用场景
闭包迭代器
简单直接,无额外开销
状态复杂时代码臃肿
简单线性迭代
结构体迭代器
状态管理清晰,可复用
需要定义类型
复杂状态迭代
通道迭代器
原生支持并发,流式处理
通道开销,可能阻塞
并发生产-消费场景
Go 1.22+ 生成器
语法简洁,内存高效
需要 Go 1.22+
所有新项目
闭包迭代器
func SliceIterator(s []string) func() (string, bool) {
i := 0
return func() (string, bool) {
if i < len(s) {
val := s[i]
i++
return val, true
}
return "", false
}
}
func main() {
iters := SliceIterator([]string{"hello", "me", "too"})
for {
if v, ok := iters(); !ok {
break
} else {
fmt.Println(v)
}
}
}
结构体迭代器
type Iterator[T any] interface {
Next() bool
Value() T
Err() error
}
// 文件行迭代器
type LineIterator struct {
scanner *bufio.Scanner
current string
err error
}
func NewLineIterator(r io.Reader) *LineIterator {
return &LineIterator{
scanner: bufio.NewScanner(r),
}
}
func (it *LineIterator) Next() bool {
if it.scanner.Scan() {
it.current = it.scanner.Text()
return true
}
it.err = it.scanner.Err()
return false
}
func (it *LineIterator) Value() string {
return it.current
}
func (it *LineIterator) Err() error {
return it.err
}
// 使用
file, _ := os.Open("data.txt")
defer file.Close()
iter := NewLineIterator(file)
for iter.Next() {
fmt.Println(iter.Value())
}
if err := iter.Err(); err != nil {
log.Fatal("读取错误:", err)
}
通道迭代器
func ChannelIterator(s []string) <-chan string {
ch := make(chan string)
go func() {
defer close(ch)
for _, v := range s {
ch <- v
}
}()
return ch
}
// 使用
for val := range ChannelIterator([]string{"X", "Y", "Z"}) {
fmt.Println(val) // 输出 X, Y, Z
}
最后更新于