php生成器的使用
按照php的文档说明
一个生成器函数看起来像一个普通的函数,不同的是普通函数返回一个值,而一个生成器可以yield生成许多它所需要的值。
当一个生成器被调用的时候,它返回一个可以被遍历的对象.当你遍历这个对象的时候(例如通过一个foreach循环),PHP 将会在每次需要值的时候调用生成器函数,并在产生一个值之后保存生成器的状态,这样它就可以在需要产生下一个值的时候恢复调用状态。
一旦不再需要产生更多的值,生成器函数可以简单退出,而调用生成器的代码还可以继续执行,就像一个数组已经被遍历完了。
一个生成器不可以返回值: 这样做会产生一个编译错误。然而return空是一个有效的语法并且它将会终止生成器继续执行。
/**
* 安原来的写法,我需要一个方法来整理数据。nums()会返回一个数组或者其他可以迭代的数据
* 然后再遍历这个数组
*/
function nums() {
$array = array();
for ($i = 0; $i < 10000; ++$i) {
$array[]= $i;
}
return $array;
} foreach (nums() as $v){
var_dump($v);
}; /**
* 但是用了yield之后,我不再需要创建一个变量,来存储这个数据。
* 而是在内部会为生成的值配对连续的整型索引,就像一个非关联的数组。
* 这样会省掉很大的内存开销
*/
function nums2() {
for ($i = 0; $i < 10000; ++$i) {
yield $i;
}
} foreach (nums2() as $v){
var_dump($v);
};
如果需要在生成器中指定下标 可以 yield $id => $fields;
$handler=function() {
$start = microtime(true);
yield;
$use_time = (microtime(true) - $start) * 1000;
echo "the time is ".(int)$use_time."ms\n";
yield;
$use_time = (microtime(true) - $start) * 1000;
echo "the time2 is ".(int)$use_time."ms\n";
};
//根据文档的说明 当一个生成器被调用的时候,它返回一个可以被遍历的对象.当你遍历这个对象的时候
//PHP 将会在每次需要值的时候调用生成器函数,
//也就是说此时并没有真的调用$handler中定义的函数。而是返回了一个生成器
$generator = call_user_func_array($handler,array());
if ($generator && $generator instanceof \Generator) {
//当对生成器进行迭代的时候,才会真正的调用该$handler中定义的函数
if ($generator->current() === false) {
/***do some thing**/
}
}
生成器也可以通过引用来使用
/**
* 使用引用来生成值
*/
function &gen_reference() {
$value = 3; while ($value > 0) {
yield $value;
}
}
/*
* 我们可以在循环中修改$number的值,而生成器是使用的引用值来生成,所以gen_reference()内部的$value值也会跟着变化。
*/
foreach (gen_reference() as &$number) {
echo (--$number).'... ';
}
除了通过引用来改变生成器中的数据之外,我们还可以使用send方法传递数据
function printer() {
while (true) {
$string = yield;
echo $string;
}
}
$printer = printer();
$printer->send('Hello world!');
但是上面的例子如果没有 while(true),那么无论后面send多少次,该生成器只会执行一次。如此说来,似乎可以用这个来控制本函数调用的最多次数?
除了向里面传递数据之外,还可以throw异常。
function application() {
while (true){
try {
yield;
}catch (Exception $e){
echo $e;
}
}
}
$printer = application();
$printer->throw(new Exception("test"));
生成器的嵌套
/**
* 在php7中 可以通过yield from 进行嵌套
*/
function count_to_ten() {
yield 1;
yield 2;
yield from [3, 4];
yield from new ArrayIterator([5, 6]);
yield from seven_eight();
yield 9;
yield 10;
} function seven_eight() {
yield 7;
yield from eight();
} function eight() {
yield 8;
} $gen = count_to_ten();
foreach ($gen as $num) {
echo "$num ";
}
echo "the return value is ".$gen->getReturn();
php生成器的使用的更多相关文章
- 介绍一款原创的四则运算算式生成器:CalculateIt2
家里小朋友读一年级了,最近每天都有一些10以内的加减法口算练习,作为程序员爸爸,自然也是想办法能够偷懒,让电脑出题,给小朋友做些练习.于是,自己在业余时间开发了一个四则运算算式生成器,名为:Calcu ...
- 每天一个设计模式-7 生成器模式(Builder)
每天一个设计模式-7 生成器模式(Builder) 一.实际问题 在讨论工厂方法模式的时候,提到了一个导出数据的应用框架,但是并没有涉及到导出数据的具体实现,这次通过生成器模式来简单实现导出成文本,X ...
- Objective-C 生成器模式 -- 简单实用和说明
1.生成器模式的定义 将一个复杂的对象的构件与它的表示分离,使得同样的构建过程可以创建不同的表示 2.生成器模式的UML Builder :生成器接口,定义创建一个Product各个部件的操作 Con ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(25)-权限管理系统-系统管理员(附生成器)
系列目录 这一节我们要着手建立系统管理员表,但发布之前,我先发布一个代码生成器给大家先用着. 这个生成器是为这个项目而生的,理论不能用于其他项目,而且写得比较潦草,但能用 下载地址 有兴趣要生成器源码 ...
- Python(四)装饰器、迭代器&生成器、re正则表达式、字符串格式化
本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解 ...
- ES6笔记(5)-- Generator生成器函数
系列文章 -- ES6笔记系列 接触过Ajax请求的会遇到过异步调用的问题,为了保证调用顺序的正确性,一般我们会在回调函数中调用,也有用到一些新的解决方案如Promise相关的技术. 在异步编程中,还 ...
- C#/ASP.NET完善的DBHelper,配套Model生成器
支持Oracle.MSSQL.MySQL.SQLite四种数据库,支持事务,支持对象关系映射:已在多个项目中实际使用. 没有语法糖,学习成本几乎为0,拿来即用. DBHelper类完整代码: usin ...
- Python 生成器与迭代器 yield 案例分析
前几天刚开始看 Python ,后因为项目突然到来,导致Python的学习搁置了几天.然后今天看回Python 发现 Yield 这个忽然想不起是干嘛用的了(所以,好记性不如烂笔头.).然后只能 花点 ...
- Mockjs,模拟数据生成器
(推荐使用)Mock.js是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试. 提供了以下模拟功能: 1. 根据数据模板生成模拟数据. 2. 模拟Ajax请求,生成并返回模拟 ...
- GUID生成器
这个GUID生成器是一个小巧的软件,属于笔者在空余时间开发的. http://pan.baidu.com/s/1sk6VGpn
随机推荐
- --- shell 扩展的顺序
1. 扩展(expansion)是bash 解释器的重要的概念: 2. 命令替换是扩展里面的一种 3. 基本结构是: “字符串准备(花括号,波浪线,参数和变量扩展,命令替换),单词分割,路径扩展” h ...
- java MAVEN 项目出现红叉
pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w ...
- WEB测试方法及注意地方
1页面部分(1) 页面清单是否完整(是否已经将所需要的页面全部都列出来了)(2) 页面是否显示(在不同分辨率下页面是否存在,在不同浏览器版本中页面是是否显示)(3) 页面在窗口中的显示是否正确.美观( ...
- ArcEngine中打开各种数据源(WorkSpace)的连接
(SDE.personal/File.ShapeFile.CAD数据.影像图.影像数据集) ArcEngine 可以接受多种数据源.在开发过程中我们使用了如下几种数据源 1.企业数据库(SDE) 企业 ...
- Flex 中画图工具(drawTool)失效
做项目的时候画图工具突然失效,解决了半天都不行,最后将画图结束的函数map_drawEndHandler写在方法里面的时候,运行却能够画图了,不知道是什么原理,比较头疼,左思右想,都感觉有点怪怪的,虽 ...
- 运行Java cmd程序 找不到或无法加载主类怎么解决
//这个问题原因有以下几种,但是和环境变量并没有太大的关系 //能够执行java 和 javac 就证明你的环境变量已经配置好了,其实 classpath 可以不配置 //假如有如下文件:H:\cod ...
- jquery each循环,
jquery each循环,要实现break和continue的功能: break----用return false; continue --用return ture; each()函数是基本上所有的 ...
- 你不知道的函数节流,提高你的JS性能!
浏览器的DOM计算处理非常耗费CPU时间,霸占内存,这对我们的开发来说是非常不友好的,,比如IE浏览器的onresize事件就可能在用户稍微拖动一下窗口时计算上千次,甚至更高频率直接让浏览器崩溃... ...
- virtualbox 下windows与虚拟机实现文件共享---挂载
1.创建挂载目录: mkdir /mnt/share 2.挂载:mount /dev/cdrom /mnt/share 3.cd /mnt/share 3.虚拟机-设备-分配光驱-VBoxGuestA ...
- java_method_数据去重
/** * 判断list本身是否有重复数据和标题 * * @param list * @return newList 返回没有重复数据的list */ public List<String[]& ...