惰性数值生成器是指在须要的时候才生成下一个数值,不须要的时候就卡在那。这和python的列表推导表达式相似。惰性生成器的好处是不会一次性将所有结果返回或放进内存,而是每次只返回一个,这样不会在某一时刻大量占用内存和其它资源。python
好比,要生成10W个数值,若是要迭代这10W个数值,有两种方法。第一种方法是将10W个数值所有生成好放进一个数组(或其它数据结构),而后再去数组中取数据。第二种方法是迭代到哪一个数值的时候临时去生成这个数值。它们的区别是显然的:第一种方法会占用大量内存,且速度有可能会很慢,第二种方法每次只占用一个数值的内存空间,用完就丢了。数组
下面是一个不算完美的惰性数值生成器示例:数据结构
package main import ( "fmt" ) func generateNums(nums chan int) { num := 0 go func() { for { num++ nums <- num } }() } func getNums(nums chan int) int { return <-nums } func main() { nums := make(chan int) generatenums(nums) for i := 0; i < 10; i++ { fmt.Println(getnums(nums)) } }
其中generateNums()函数是惰性数值生成器,它使用一个nums channel做为参数,每次生成的数值都会放进这个channel中。函数
getNums()函数是取出存入nums channel中的数并返回。code
理论上一切都很简单,只要在须要的地方调用generateNums()函数便可。但问题在于若是多个地方调用generateNums(),各个地方的nums通道将互相影响。因此,应该改进一下,让generateNums()自带属于本身的nums通道,而不是多个generateNums()共享一个nums通道。内存
func generateNums(nums chan int) {} | \|/ func generateNums(){ nums := make(chan int) }
由于通道私有了,要想从这个通道中取数据,须要将这个通道做为返回值:资源
func generateNums() chan int{ nums := make(chan int) ... return nums }
这样每次调用generateNums()就取得了它的数值生成器通道:get
nums := generateNums()
下面是改良后的惰性数值生成器:import
package main import ( "fmt" ) func generatenums() chan int { nums := make(chan int) num := 0 go func() { for { num++ nums <- num } }() return nums } func getnums(nums chan int) int { return <-nums } func main() { nums := generatenums() for i := 0; i < 10; i++ { fmt.Println(getnums(nums)) } }