您现在的位置是:首页 > 编程 > 

Go程序例子(25):遍历迭代器

2025-07-29 05:48:06
Go程序例子(25):遍历迭代器 从 1.2 版本开始,Go 语言增加了对迭代器的支持,这让我们几乎可以对任何东西进行 range 遍历!代码语言:go复制package main import ( "fmt" "iter" "slices" ) // 让我们再次看看前面示例中的 List 类型。在那个示例中,

Go程序例子(25):遍历迭代器

从 1.2 版本开始,Go 语言增加了对迭代器的支持,这让我们几乎可以对任何东西进行 range 遍历!

代码语言:go复制
package main

import (
    "fmt"
    "iter"
    "slices"
)
// 让我们再次看看前面示例中的 List 类型。在那个示例中,我们有一个 AllElements 方法,它返回列表中所有元素的切片。使用 Go 的迭代器,我们可以做得更好——如下所示。
type List[T any] struct {
    head, tail *element[T]
}

type element[T any] struct {
    next *element[T]
    val  T
}

func (lst *List[T]) Push(v T) {
    if  == nil {
        lst.head = &element[T]{val: v}
         = lst.head
    } else {
        .next = &element[T]{val: v}
         = .next
    }
}
// ll 返回一个迭代器,在 Go 中,它是一个具有特殊签名的函数。
func (lst *List[T]) All() iter.Seq[T] {
    return func(yield func(T) bool) {
		// 迭代器函数接受另一个函数作为参数,通常称为 yield(但名称可以是任意的)。它会在每个我们想要迭代的元素上调用 yield,并注意 yield 的返回值,以便在需要时提前终止迭代。
        for e := lst.head; e != nil; e =  {
            if !yield(e.val) {
                return
            }
        }
    }
}
// 迭代不需要底层数据结构,甚至不必是有限的!这里有一个返回斐波那契数列迭代器的函数:只要 yield 一直返回 true,它就会继续运行。
func genFib() iter.Seq[int] {
    return func(yield func(int) bool) {
        a, b := 1, 1

        for {
            if !yield(a) {
                return
            }
            a, b = b, a+b
        }
    }
}

func main() {
    lst := List[int]{}
    lst.Push(10)
    lst.Push(1)
    lst.Push(2)
	// 由于 List.All 返回一个迭代器,我们可以在常规的 range 循环中使用它。
    for e := range lst.All() {
        fmt.Println(e)
    }
	// 像 slices 这样的包提供了许多有用的函数来处理迭代器。例如,Collect 接受任何迭代器,并将其所有值收集到一个切片中。
    all := slices.Collect(lst.All())
    fmt.Println("all:", all)

    for n := range genFib() {
		// 一旦循环遇到 break 或提前返回,传递给迭代器的 yield 函数将返回 false。
        if n >= 10 {
            break
        }
        fmt.Println(n)
    }
}

运行结果:

代码语言:javascript代码运行次数:0运行复制
$ go run range-over-iterators.go
10
1
2
all: [10 1 2]
1
1
2

5
8

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1256863.html

相关标签:无
上传时间: 2025-07-28 03:21:58
留言与评论(共有 16 条评论)
本站网友 银行账户冻结
13分钟前 发表
1 for { if !yield(a) { return } a
本站网友 满月
16分钟前 发表
它会在每个我们想要迭代的元素上调用 yield
本站网友 迪文
0秒前 发表
Collect 接受任何迭代器
本站网友 莆田团购
3分钟前 发表
= List[int]{} lst.Push(10) lst.Push(1) lst.Push(2) // 由于 List.All 返回一个迭代器
本站网友 网上买燕窝
12分钟前 发表
for e
本站网友 利川市政府
17分钟前 发表
func (lst *List[T]) All() iter.Seq[T] { return func(yield func(T) bool) { // 迭代器函数接受另一个函数作为参数
本站网友 1点
29分钟前 发表
Collect 接受任何迭代器
本站网友 中国糖网
9分钟前 发表
使用 Go 的迭代器
本站网友 异步电机
17分钟前 发表
v} = .next } } // ll 返回一个迭代器
本站网友 男友忘不了前女友
12分钟前 发表
我们有一个 AllElements 方法
本站网友 始乱终弃的意思
12分钟前 发表
v} = .next } } // ll 返回一个迭代器
本站网友 唐亮工长俱乐部
18分钟前 发表
它会在每个我们想要迭代的元素上调用 yield
本站网友 神州租车深圳
12分钟前 发表
这让我们几乎可以对任何东西进行 range 遍历!代码语言:go复制package main import ( "fmt" "iter" "slices" ) // 让我们再次看看前面示例中的 List 类型
本站网友 尿不湿哪个牌子好
21分钟前 发表
[10 1 2] 1 1 2 5 8
本站网友 万杰医院
23分钟前 发表
type List[T any] struct { head