惰性數值生成器是指在須要的時候才生成下一個數值,不須要的時候就卡在那。這和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)) } }