在Go中创建迭代器的最惯用的方法是什么?

一个选择是使用频道。通道类似于迭代器,您可以使用range关键字迭代它们。但是当你发现你不能脱离这个循环,而不会泄漏goroutine的用法变得有限。

什么是惯用的方法来创建迭代器模式?

编辑:

渠道的根本问题是推动模式。迭代器是一个拉模型。你不需要告诉迭代器停止。我正在寻找一种以愉快的表现方式迭代集合的方法。我也想链接迭代器(map,filter,fold alternative)。

频道是有用的,但关闭通常更为合适。

package main

import "fmt"

func main() {
    gen := newEven()
    fmt.Println(gen())
    fmt.Println(gen())
    fmt.Println(gen())
    gen = nil // release for garbage collection
}

func newEven() func() int {
    n := 0
    // closure captures variable n
    return func() int {
        n += 2
        return n
    }
}

游乐场:http://play.golang.org/p/W7pG_HUOzw

不喜欢闭包吗?使用带有方法的命名类型:

package main

import "fmt"

func main() {
    gen := even(0)
    fmt.Println(gen.next())
    fmt.Println(gen.next())
    fmt.Println(gen.next())
}

type even int

func (e *even) next() int {
    *e += 2
    return int(*e)
}

游乐场:http://play.golang.org/p/o0lerLcAh3

这三种技术之间有权衡,所以你不能将其称为惯用语。尽量满足您的需求。

链接很容易,因为函数是第一类对象。这是关闭示例的扩展。我为整数生成器添加了一个类型intGen,它使得生成器函数被用作参数和返回值。 mapInt以通用方式定义,以将任何整数函数映射到整数生成器。其他功能如过滤器和折叠也可以类似地定义。

package main

import "fmt"

func main() {
    gen := mapInt(newEven(), square)
    fmt.Println(gen())
    fmt.Println(gen())
    fmt.Println(gen())
    gen = nil // release for garbage collection
}

type intGen func() int

func newEven() intGen {
    n := 0
    return func() int {
        n += 2
        return n
    }
}

func mapInt(g intGen, f func(int) int) intGen {
    return func() int {
        return f(g())
    }
}

func square(i int) int {
    return i * i
}

游乐场:http://play.golang.org/p/L1OFm6JuX0

http://stackoverflow.com/questions/14000534/what-is-most-idiomatic-way-to-create-an-iterator-in-go

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:在Go中创建迭代器的最惯用的方法是什么?