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
