自考网站建设与管理,数据库设计对网站开发的影响,长沙网站建设做得好的,站长论坛#x1f308;Don’t worry , just coding! 内耗与overthinking只会削弱你的精力#xff0c;虚度你的光阴#xff0c;每天迈出一小步#xff0c;回头时发现已经走了很远。
#x1f4d7;概念 在 Go 语言中#xff0c;迭代器的实现通常不是通过语言内置的迭代器类型#x…
Don’t worry , just coding! 内耗与overthinking只会削弱你的精力虚度你的光阴每天迈出一小步回头时发现已经走了很远。
概念 在 Go 语言中迭代器的实现通常不是通过语言内置的迭代器类型而是通过自定义类型和方法来实现的。下面是一个简单的示例展示如何在 Go 中实现一个迭代器。 代码
迭代器
package mainimport fmt// IntSliceIterator 是一个自定义的迭代器用于迭代整数切片
type IntSliceIterator struct {//data存储要迭代的整数切片。//index当前迭代的位置。data []intindex int
}// 定义NewIntSliceIterator函数输入data切片类型为int
// 返回一个指向 IntSliceIterator 结构体的指针。
func NewIntSliceIterator(data []int) *IntSliceIterator {//IntSliceIterator{} 创建了一个新的 IntSliceIterator 实例并返回return IntSliceIterator{data: data,index: 0,}
}// HasNext 检查是否还有下一个元素
func (it *IntSliceIterator) HasNext() bool {return it.index len(it.data)
}// 定义Next函数 返回下一个元素并移动迭代器
// 输入*IntSliceIterator指针赋值给it变量
// 返回一个int类型
func (it *IntSliceIterator) Next() int {if !it.HasNext() {//如果没有更多元素使用 panic 抛出一个错误panic(No more elements)}//从data 切片中获取当前索引 it.index 指向的元素并将其赋值给 value。value : it.data[it.index]//将 index 增加 1下次调用时指向下一个元素。it.indexreturn value
}func main() {data : []int{1, 2, 3, 4, 5}iterator : NewIntSliceIterator(data)for iterator.HasNext() {fmt.Println(iterator.Next())}
}//输出
//1
//2
//3
//4
//5
yeild
在python中yeild表示本次执行结束并返回值类似于returnyeild和return不同的地方在于yeild可以优雅的返回每次调用时的值。 在go中没有yeild关键字我们用yeild方便理解。
package mainimport (fmtiterslices
)// 这不是来了么定义一个泛型List 任意类型的struct
type List[T any] struct {head, tail *element[T]
}// 老样子定义element泛型struct 任意类型是一个链表
type element[T any] struct {next *element[T]val T
}// 链表的push方法
func (lst *List[T]) Push(v T) {if lst.tail nil {lst.head element[T]{val: v}lst.tail lst.head} else {lst.tail.next element[T]{val: v}lst.tail lst.tail.next}
}// 输入为lst类型为 *List[T]返回一个函数这个函数的类型是 iter.Seq[T]是一个迭代器
func (lst *List[T]) All() iter.Seq[T] {//返回值是一个匿名函数接受一个参数 yield这个参数是一个函数类型接受一个类型为 T 的参数并返回一个布尔值return func(yield func(T) bool) {//初始化 e 为链表的头节点//循环条件为 e ! nil//e e.next 将e指向链表下一个节点for e : lst.head; e ! nil; e e.next {//调用yield如果yield 返回 false则退出循环结束遍历if !yield(e.val) {return}}}
}// 斐波那契数列生成
// 定义函数genFib
// 输入参数没有
// 返回一个函数 int类型
func genFib() iter.Seq[int] {//返回一个匿名函数func该匿名函数接受一个参数 yield这个参数是一个函数类型接受一个 int 类型的参数并返回一个布尔值。return func(yield func(int) bool) {//赋值a, b : 1, 1//调用yield如果yield 返回 false则退出循环for {if !yield(a) {return}a, b b, ab}}
}func main() {lst : List[int]{}lst.Push(10)lst.Push(13)lst.Push(23)for e : range lst.All() {fmt.Println(e)}//lst 是一个链表调用 All() 方法会返回一个迭代器//这个生成器会遍历链表中的所有元素并通过 yield 函数逐个返回这些元素。all : slices.Collect(lst.All()) //slices.Collect(...) 函数遍历生成器收集所有元素fmt.Println(all:, all)//调用genFib赋值给nfor n : range genFib() {//当n10跳出循环if n 10 {break}fmt.Println(n)}
}//输出
//10
//13
//23
//all: [10 13 23]
//1
//1
//2
//3
//5
//8Tips小知识点
迭代器和生成器 在 Go 语言中生成器和迭代器是处理序列数据的两种不同概念虽然它们有相似之处但在实现和使用上有一些关键的区别。 生成器是一种函数它可以逐步生成一系列值而不是一次性返回所有值。生成器通常使用 yield 关键字在 Go 中通常通过返回一个函数来模拟来返回下一个值并保持其状态以便在下一次调用时继续执行。生成器通常在需要时生成值适用于需要惰性求值的场景。调用生成器时可以获取下一个值而不需要事先知道所有值。生成器通过闭包保持状态允许在多次调用之间保留局部变量的值。迭代器是一种对象它实现了特定的接口通常包含 Next() 方法用于遍历集合中的元素。迭代器维护一个内部状态允许用户逐步访问集合的每个元素。迭代器通常用于遍历整个集合通过调用 Next() 方法来获取下一个元素直到没有更多元素可供访问。迭代器通过结构体的字段来管理状态通常在结构体中维护当前元素的指针或索引。
生成器Example
func genFib() func() int {a, b : 0, 1return func() int {a, b b, abreturn a}
}迭代器Example
type Iterator struct {current *Node
}func (it *Iterator) Next() *Node {if it.current nil {return nil}node : it.currentit.current it.current.nextreturn node
}
无人扶我青云志我自踏雪至山巅。