zoukankan      html  css  js  c++  java
  • Go基础系列:惰性数值生成器

    惰性数值生成器是指在需要的时候才生成下一个数值,不需要的时候就卡在那。这和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中的数并返回。

    理论上一切都很简单,只要在需要的地方调用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()就取得了它的数值生成器通道:

    nums := generateNums()
    

    下面是改良后的惰性数值生成器:

    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))
    	}
    }
    
  • 相关阅读:
    两种方法生成随机字符串
    cmd命令总结
    NOI前乱写
    多校模拟9
    字符串 口胡
    HEOI2020游记
    省选模拟104
    省选模拟103
    省选模拟102
    省选模拟101
  • 原文地址:https://www.cnblogs.com/f-ck-need-u/p/10009892.html
Copyright © 2011-2022 走看看