Go 1.23 迭代器详解

科技   2024-11-25 13:29   广东  

迭代器概述

其他编程语言多年来一直拥有迭代器这一结构。Go 在 1.23 版本中引入了迭代器。迭代器是一种用于遍历数据结构(如切片、映射等)元素的“抽象”。虽然使用索引也能达到相同的效果,但迭代器通过抽象循环逻辑,提供了不仅仅是遍历所有元素的功能。它们可以过滤切片并创建批次(参见 myslices.Chunks 文章)。通过迭代器,你可以在循环的代价下完成更多的事情。

在 Go 1.23 之前的切片遍历方法

在 Go 1.23 之前,你有多种选择来遍历切片的元素:

  • Do While / While 循环
  • For 循环
  • Range 循环

从 Go 1.23 开始

正如我们在介绍中提到的,Go 1.23 引入了迭代器来遍历数据结构的元素。那么,Go 中的迭代器是什么呢?

根据文档,迭代器是一个函数,它将序列的连续元素传递给一个回调函数(生成器),通常称为 yield。当序列结束或生成器函数返回 false 时,迭代器函数会停止,表示迭代应该提前终止。

编写一个切片迭代器

让我们编写一个迭代器来遍历切片的元素。乍一看可能有些复杂,深入理解后也是如此。😆

我们将其分解为几个部分来理解它的功能:

  1. sliceValueIterator:迭代器函数是一个可以在 range 语句后调用的函数;
  2. 迭代器函数以切片(slice []int)作为参数;
  3. 迭代器函数返回一个以生成器(yield)作为参数的函数;
  4. 生成器是一个函数,接受切片的值并返回一个布尔值:当这个布尔值为 false 时,迭代器将停止循环的执行;
  5. 传递给生成器函数的参数是你想在循环中读取的值。在这个例子中是 value

如果我们还想获取索引,我们可以这样写:

现在我们在循环中需要两个值:

  • 项目的索引
  • 项目的值

根据第 5 点,生成器必须接受两个值。可以看到,generatorWithIndex 是一个接受两个整数作为参数并返回布尔值的函数。完美!

Seq 和 Seq2 类型

在标准库中,你会发现这两种类型定义在 iter 包中:

  • Seq
  • Seq2

它们与 func(generator)func(generatorWithIndex) 类型相同,但使用了泛型,因此你可以生成任何类型的值。它们定义如下:

type (
    Seq[V any]     func(yield func(V) bool)
    Seq2[K, V any] func(yield func(K, V) bool)
)

如果我们用这些类型重写示例,我们会得到:

结论

我认为对于像这样的简单任务,使用迭代器并没有明显的优势。这里使用的示例旨在介绍和理解 Go 1.23 中这个新概念的基本原理。希望这篇文章能帮助你更好地理解标准库中如 slices 包中那些新函数背后的机制。

点击关注并扫码添加进交流群
 免费领取「Go 语言」学习资料  


源自开发者
专注于提供关于Go语言的实用教程、案例分析、最新趋势,以及云原生技术的深度解析和实践经验分享。
 最新文章