Golang迭代器模式集合遍历与使用方法

Go语言通过闭包和函数实现迭代器模式,可遍历集合且不暴露内部结构;Go 1.18支持泛型后能编写通用迭代器;可借助接口统一不同数据结构的遍历方式,适用于切片、二叉树等场景,核心是封装状态、简化调用。

golang迭代器模式集合遍历与使用方法

在Go语言中,虽然没有像C++或Java那样的显式迭代器接口,但通过函数、闭包和接口的组合,可以优雅地实现迭代器模式。这种模式适用于需要遍历集合对象且不暴露其内部结构的场景,比如遍历树、链表或自定义数据结构。

基本迭代器设计思路

Go中的迭代器通常通过函数返回一个无参数、返回值为元素和布尔值的闭包来实现。每次调用该函数,返回下一个元素和是否还有元素的标志。

以一个整型切片为例:

func intSliceIterator(slice []int) func() (int, bool) {    index := 0    return func() (int, bool) {        if index >= len(slice) {            return 0, false        }        val := slice[index]        index++        return val, true    }}

使用方式如下:

立即学习“go语言免费学习笔记(深入)”;

iter := intSliceIterator([]int{1, 2, 3})for {    val, hasNext := iter()    if !hasNext {        break    }    fmt.Println(val)}

泛型迭代器(Go 1.18+)

Go 1.18引入泛型后,可以编写通用的迭代器,适用于任意类型集合。

func sliceIterator[T any](slice []T) func() (T, bool) {    index := 0    return func() (T, bool) {        var zero T        if index >= len(slice) {            return zero, false        }        val := slice[index]        index++        return val, true    }}

调用时指定类型或由编译器推导:

iter := sliceIterator([]string{"a", "b", "c"})for val, ok := iter(); ok; {    fmt.Println(val)}

结构体集合的迭代器实现

对于复杂数据结构,如二叉树,迭代器能隐藏遍历逻辑。

type TreeNode struct {    Val   int    Left  *TreeNode    Right *TreeNode}func inorderIterator(root *TreeNode) func() (int, bool) {    stack := []*TreeNode{}    current := root    return func() (int, bool) {        for current != nil || len(stack) > 0 {            for current != nil {                stack = append(stack, current)                current = current.Left            }            current = stack[len(stack)-1]            stack = stack[:len(stack)-1]            val := current.Val            current = current.Right            return val, true        }        return 0, false    }}

中序遍历二叉树变得简洁:

iter := inorderIterator(root)for val, hasNext := iter(); hasNext; {    fmt.Println(val)}

接口方式统一迭代行为

定义统一的迭代器接口,便于在不同集合间切换:

type Iterator[T any] interface {    Next() (T, bool)}type SliceIterator[T any] struct {    slice []T    index int}func (it *SliceIterator[T]) Next() (T, bool) {    var zero T    if it.index >= len(it.slice) {        return zero, false    }    val := it.slice[it.index]    it.index++    return val, true}

使用接口后,调用逻辑更清晰:

var iter Iterator[int] = &SliceIterator[int]{slice: []int{1, 2, 3}}for val, ok := iter.Next(); ok; {    fmt.Println(val)}

基本上就这些。Go的迭代器靠闭包和函数返回实现最常见,泛型加持后更灵活。接口方式适合大型项目统一抽象,而简单场景用闭包就够了。关键是把遍历状态封装好,调用方无需关心内部怎么走。

以上就是Golang迭代器模式集合遍历与使用方法的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1403034.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月15日 19:13:52
下一篇 2025年12月15日 19:14:09

相关推荐

发表回复

登录后才能评论
关注微信