什么是生成器Generators
生成器允许你在 foreach 代码块中写代码来迭代一组数据而不需要在内存中创建一个数组, 那会使你的内存达到上限,或者会占据可观的处理时间。相反,你可以写一个生成器函数,就像一个普通的自定义函数一样, 和普通函数只返回一次不同的是, 生成器可以根据需要 yield 多次,以便生成需要迭代的值。
一个简单的例子就是使用生成器来重新实现 range() 函数。 标准的 range() 函数需要在内存中生成一个数组包含每一个在它范围内的值,然后返回该数组, 结果就是会产生多个很大的数组。 比如,调用 range(0, 10000) 将导致内存占用超过 4 MB。
例子代码
= 0) { throw new LogicException('Step must be -ve'); } for ($i = $start; $i >= $limit; $i += $step) { yield $i; } } } if ($argc === 1) { $iterate = rangeWithGenerators(0, $num, 1); foreach ($iterate as $value){ echo $value . "\\n"; } //var\_dump(iterator\_to\_array($iterate)); } if ($argc === 2) { $test = range(0, $num, 1); foreach ($test as $value) { echo $value . "\\n"; } } $end = xdebug\_memory\_usage(); echo sprintf("内存消耗量%s\\n", convert($end-$start)); function convert($size){ $unit=array('b','kb','mb','gb','tb','pb'); return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit\[$i\]; } **环境** * PHP7.1 * Xdebug **执行命令** * php test.php 结果返回:内存消耗量416 b * php test.php range 结果返回:内存消耗量4 mb **测试结果论述** * 通过代码的执行,比较除了PHP标准函数rang()和自定义函数rangeWithGenerators()之间的异同。实现了同样的目的,却消耗着不同的内存,生成器的优点显而易见。 * rangeWithGenerators()使用了生成器,而生成器的关键就是使用yield关键词,yield常见的使用涉及到foreach和for两个流程控制语句。rangeWithGenerators()中for循环yield变量$i(yield可理解为生成-值,如同return可理解为返回-值)。 * rangeWithGenerators()函数返回的便是一个生成器Generators( 使用var\_dump($iterate)查看其类型 )。 * 既然rangeWithGenerators()函数返回的是一个生成器,我们可以使用以下两种方式来使用: * foreach循环该Generators,本例子中则使用该方法读取Generators。 * PHP标准函数iterator\_to\_array(),该函数将Generators转换为一个Array。 * 使用场景,可查阅参考资料2 参考资料: 1. [http://php.net/manual/zh/language.generators.overview.php](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fphp.net%2Fmanual%2Fzh%2Flanguage.generators.overview.php) 2. [实际生产中的使用](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fsegmentfault.com%2Fa%2F1190000012334856%23articleHeader8)