php[024]生成器
coding
在 php 中有生成器这个东西。
官方的描述是
生成器提供了一种更容易的方法来实现简单的对象迭代,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低。
生成器允许你在 foreach 代码块中写代码来迭代一组数据而不需要在内存中创建一个数组, 那会使你的内存达到上限,或者会占据可观的处理时间。相反,你可以写一个生成器函数,就像一个普通的自定义函数一样, 和普通函数只返回一次不同的是, 生成器可以根据需要 yield 多次,以便生成需要迭代的值。
以及官方提供的改造range的代码。
<?php
function xrange($start, $limit, $step = 1) {
if ($start <= $limit) {
if ($step <= 0) {
throw new LogicException('Step must be positive');
}
for ($i = $start; $i <= $limit; $i += $step) {
yield $i;
}
} else {
if ($step >= 0) {
throw new LogicException('Step must be negative');
}
for ($i = $start; $i >= $limit; $i += $step) {
yield $i;
}
}
}
/*
* 注意下面range()和xrange()输出的结果是一样的。
*/
echo 'Single digit odd numbers from range(): ';
foreach (range(1, 9, 2) as $number) {
echo "$number ";
}
echo "\n";
echo 'Single digit odd numbers from xrange(): ';
foreach (xrange(1, 9, 2) as $number) {
echo "$number ";
}
在我第一次看到的时候并没有思考为什么叫生成器这个东西。所以在一段时间内产生了迷惑。其实用官方编写的函数样本赋值给变量var_dump
出来的结果会是一个对象,而其生成器的名字是因为其可以通过foreach
在循环的每次成产出结果。所以可以看以下代码,来感受以下yield
解决了什么问题。
<?php
function xrange($start, $limit, $step = 1) {
if ($start <= $limit) {
if ($step <= 0) {
throw new LogicException('Step must be positive');
}
for ($i = $start; $i <= $limit; $i += $step) {
yield $i;
}
} else {
if ($step >= 0) {
throw new LogicException('Step must be negative');
}
for ($i = $start; $i >= $limit; $i += $step) {
yield $i;
}
}
}
$xarr = xrange(0,9,1);
// 可以理解 $xarr 并不能用 一些数组切割的方式去做一些事情,因为其本身不是数组。
foreach($xarr as $v){
echo $v;
}
// 所以上述整体是做了这个
for($i = 0 ;$i<10;$i++){
echo $i;
}
$arr = range(0,9,1);
foreach($arr as $v){
echo $v;
}
以及更好看的文件读取编码方式
function readTxt()
{
# code...
$handle = fopen("./test.txt", 'rb');
while (feof($handle)===false) {
# code...
yield fgets($handle);
}
fclose($handle);
}
foreach (readTxt() as $key => $value) {
# code...
echo $value.'<br />';
}
所以在某种程度,我更倾向于,这是一个特殊写法的语法糖。可以在某些方式上以优雅的形式去实现代码。
评论列表