14.8 惰性生成器
...大约 2 分钟
14.8 惰性生成器
14.8.1 生成器
指的是被调用时返回序列中的下一个值的函数:
generateInteger() => 0
generateInteger() => 1
generateInteger() => 2
....
返回下一个值而不是整个序列,被称为惰性求值:仅在需要的时候获取数据,同时保留相关变量资源。比如生成一个无限数量的整数序列,再进行调用会比较困难。
package chapter_14
import "fmt"
var resume chan int
func mainLazyEvaluation() {
resume = integers()
fmt.Println(generate1()) // 0
fmt.Println(generate1()) // 1
fmt.Println(generate1()) // 2
}
func integers() chan int {
yield := make(chan int)
count := 0
go func() {
for {
yield <- count
count++
}
}()
return yield
}
func generate1() int {
return <-resume
}
14.8.2 惰性生成器工厂函数
工厂函数以函数和初始状态作为参数,返回一个无参的、返回值为生成序列的函数。
传入的函数计算出下一个返回值和下一个状态参数。
14_8_lazy_evaluator_factory.go
package chapter_14
import "fmt"
type Any interface{}
type EvalFunc func(Any) (Any, Any)
func mainLazyEvaluatorFactory() {
evenFunc := func(state Any) (Any, Any) {
os := state.(int)
ns := os + 2
return os, ns
}
even := BuildLazyIntEvaluator(evenFunc, 0)
for i := 0; i < 10; i++ {
fmt.Printf("%dth even number: %d\n", i, even())
}
}
func BuidlLazyEvaluator(evalFunc EvalFunc, initState Any) func() Any {
retChan := make(chan Any)
loopFunc := func() {
var actState Any = initState
var retVal Any
for {
retVal, actState = evalFunc(actState)
retChan <- retVal
}
}
retFunc := func() Any {
return <-retChan
}
go loopFunc()
return retFunc
}
func BuildLazyIntEvaluator(evalFunc EvalFunc, initState Any) func() int {
ef := BuidlLazyEvaluator(evalFunc, initState)
return func() int {
return ef().(int)
}
}
0th even number: 0
1th even number: 2
2th even number: 4
3th even number: 6
4th even number: 8
5th even number: 10
6th even number: 12
7th even number: 14
8th even number: 16
9th even number: 18
14.8.3 斐波那契生成器
package chapter_14
import "fmt"
func mainFibEvaluator() {
fibFunc := func(state Any) (Any, Any) {
os := state.([]uint64)
v1 := os[0]
v2 := os[1]
ns := []uint64{v2, v1 + v2}
return v1, ns
}
fib := BuildLazyUint64Evaluator(fibFunc, []uint64{0, 1})
for i := 0; i < 10; i++ {
fmt.Printf("%dth fib : %d\n", i, fib())
}
}
func BuildLazyUint64Evaluator(evalFunc EvalFunc, initState Any) func() uint64 {
ef := BuidlLazyEvaluator(evalFunc, initState)
return func() uint64 {
return ef().(uint64)
}
}
0th fib : 0
1th fib : 1
2th fib : 1
3th fib : 2
4th fib : 3
5th fib : 5
6th fib : 8
7th fib : 13
8th fib : 21
9th fib : 34
Powered by Waline v2.15.2