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))
}
}
Go基础系列:惰性数值生成器的更多相关文章
- mysql 开发基础系列6 数值与日期函数
一. 数值函数 1. abs(x) 返回x的绝对值 SELECT ABS(-0.8),ABS(0.8); 2.ceil(x) 返回大于x的最大整数 SELECT CEIL(-0.8),CEIL(0. ...
- Java基础系列-Collector和Collectors
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10748925.html 一.概述 Collector是专门用来作为Stream的coll ...
- python基础系列教程——Python3.x标准模块库目录
python基础系列教程——Python3.x标准模块库目录 文本 string:通用字符串操作 re:正则表达式操作 difflib:差异计算工具 textwrap:文本填充 unicodedata ...
- Java基础系列-二进制操作
原创文章,转载请标注出处:<Java基础系列-二进制操作> 概述 Java源码中涉及到大量的二进制操作,非常的复杂,但非常的快速. Java二进制表示法 首先了解下二进制,二进制是相对十进 ...
- SpringBoot基础系列-SpringCache使用
原创文章,转载请标注出处:<SpringBoot基础系列-SpringCache使用> 一.概述 SpringCache本身是一个缓存体系的抽象实现,并没有具体的缓存能力,要使用Sprin ...
- JavaScript基础系列
JavaScript基础系列 JavaScript是一种基于对象和事件驱动的客户端脚本语言. JavaScript的注释 // 单行 /**/ 多行注释 JavaScript变量,函数名和操作符都是区 ...
- DAX/PowerBI系列 - 关于时间系列 - 时间相关数值比较 - 用非自带函数
DAX/PowerBI系列 - 关于时间系列 - 时间相关数值比较 - 用非自带函数 文末有彩蛋,解决蛋疼问题 难度: ★★☆☆☆(2星) 适用范围: ★★★☆☆(3星) 概况: 基于时间的汇总可能是 ...
- 基础系列(4)—— C#装箱和拆箱
一 装箱和拆箱的概念 装箱是将值类型转换为引用类型 : 拆箱是将引用类型转换为值类型 : 值类型:包括原类型(Sbyte.Byte.Short.Ushort.Int.Uint.Long.Ulong.C ...
- 夯实Java基础系列9:深入理解Class类和Object类
目录 Java中Class类及用法 Class类原理 如何获得一个Class类对象 使用Class类的对象来生成目标类的实例 Object类 类构造器public Object(); register ...
随机推荐
- CodeSampler DX9 Full-screen initialization
D3D新手,请轻拍. 最近在学CodeSampler上的DX9范例.编译环境是VS2012.搭编译环境用了一两天,另行开文吐槽(有时间的话). 本文讲讲Full-screen initializati ...
- Adnroid开发环境搭建(四步搞定)
新手博友,多多关照 下面给大家介绍JDK Eclipse AndroidSDK ADT环境搭建,安装教程 第一步.安装JDK: 第二步.安装Eclipse: 第三步.下载并安装AndroidSDK: ...
- CSS伪类的理解
因为之前一直对css伪类没有过多的了解,在网上看到一段css代码,不能理解 a:hover span.title{ color:red; ......... } 现通过查询css手册,其实css伪类只 ...
- 针对zstack虚拟机导出的问题的解决办法!
1. nfs 首先定位image所在位置: 云主机--〉云盘操作--〉配置信息--〉更多信息--安装路径 /opt/zstack/nfsprimarystorage/prim-aab63dc6284f ...
- ubuntu hadoop环境搭建
安装Ubuntu系统:这个自行安装 下载jdk:我下的是1.8.0_141d的,下载好后在usr/lib下新建一个jvm的文件夹用来存放Java的文件,下载好的jdk可以在其他地方解压或者jvm里面解 ...
- 03 of learning python
01 input输入的是str类型 如果输入的是数字的话,要记得强制转换一下! 02 isdigit() 这个方法是用来检测字符串是否全部由数字组成 str.isdigit() 如果字符串只包含数字则 ...
- C++ 引用、构造函数、移动语义
1.引用 C++中的引用主要用作函数的形参,接近于const指针,必须在创建时初始化. 以Person类为例,如下: Person p; //调用P的 ...
- 常用maven仓库
常用Maven仓库网址:http://mvnrepository.com/http://search.maven.org/http://repository.sonatype.org/content/ ...
- [转] Snapshotting with libvirt for qcow2 images
http://kashyapc.com/2011/10/04/snapshotting-with-libvirt-for-qcow2-images/ Libvirt 0.9.6 was recentl ...
- ZKWeb网页框架2.2正式发布
2.2.0更新的内容有 重构依赖注入容器 使用无锁算法 (可能导致不兼容) 使用 ContainerFactoryData 创建实例 (可能导致不兼容) 删除静态的 ContainerFactoryC ...