14.8 惰性生成器

Kesa...大约 2 分钟

14.8 惰性生成器

14.8.1 生成器

指的是被调用时返回序列中的下一个值的函数:

    generateInteger() => 0
    generateInteger() => 1
    generateInteger() => 2
    ....

返回下一个值而不是整个序列,被称为惰性求值:仅在需要的时候获取数据,同时保留相关变量资源。比如生成一个无限数量的整数序列,再进行调用会比较困难。

14_8_lazy_evaluation.go

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