PHP 生成器(Generator)学习笔记

Generator

Generator implements Iterator {
/* 方法 */
public current ( ) : mixed
public key ( ) : mixed
public next ( ) : void
public rewind ( ) : void
public send ( mixed $value ) : mixed
public throw ( Exception $exception ) : void
public valid ( ) : bool
public __wakeup ( ) : void
}

Caution Generator objects cannot be instantiated via new. (Generator 对象不能通过 new 实例化.)


方法说明
Generator::current — 返回当前产生的值
Generator::key — 返回当前产生的键
Generator::next — 生成器继续执行
Generator::rewind — 重置迭代器
Generator::send — 向生成器中传入一个值
Generator::throw — 向生成器中抛入一个异常
Generator::valid — 检查迭代器是否被关闭
Generator::__wakeup — 序列化回调

建立在对Iterator的理解下,我们知道生成器允许在 foreach 代码块中写代码来迭代一组数据而不需要在内存中创建一个数组, 那会使内存达到上限,或者会占据可观的处理时间。同时,写一个生成器函数,就像一个普通的自定义函数一样, 和普通函数只返回一次不同的是, 生成器可以根据需要 yield 多次,以便生成需要迭代的值


function gen() {
    yield 'foo';
    yield 'bar';
    yield 'code';
}

$g = gen();
foreach($g as $key => $value) {
	var_dump($value,$key);
}

//string(3) "foo"
//int(0)
//string(3) "bar"
//int(1)
//string(4) "code"
//int(2)

等价于


$g = gen();
$g->rewind();

while ($g->valid())
{
    $key = $g->key();
    $value = $g->current();
    var_dump($value);
    $g->next();
}
//string(3) "foo"
//int(0)
//string(3) "bar"
//int(1)
//string(4) "code"
//int(2)

我们再来看一段代码用yied来生成斐波那契数来加深下理解

function fib($n)
{
    $cur = 1;
    $prev = 0;
    for ($i = 0; $i < $n; $i++) {
        yield $cur;
        $temp = $cur;
        $cur = $prev + $cur;
        $prev = $temp;
    }
}

$g = fib(9);

foreach($g as $key => $value) {
	var_dump($value,$key);
}

得到

//int(1)
//int(1)
//int(2)
//int(3)
//int(5)
//int(8)
//int(13)
//int(21)
//int(34)

对于所有在generator函数中出现的yield,首先它都是语句,而跟在yield后面的任何表达式的值将作为调用generator函数的返回值,如果yield后面没有任何表达式(变量、常量都是表达式),其实yield关键字在每次执行generator 的时候会在yield 关键字时"挂起"返回

function fib($n)
{
    $cur = 1;
    $prev = 0;
    for ($i = 0; $i < $n; $i++) {
        yield $cur;
        
        echo 'current key '.$i."\n";
        $temp = $cur;
        $cur = $prev + $cur;
        $prev = $temp;
    }
}

$g = fib(3);

echo $g->current();
echo "=======\n";
echo $g->next();
echo "=======\n";
echo $g->current();
//1   $this->current()
//=======    
//current key 0    $this->next() 才执行
//=======
//1

总结

  1. generator 继承iterator,通过迭代返回generator对象;
  2. 通过yield关键字声明生成器,Generator 对象不能通过 new 实例化
  3. yield关键字是挂起当前位置,下次仍会往下执行到下一个yield挂起状态区别于return;

接下来参考学习下PHP 通过yiled 与generator 对象通信

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值