php生成器2

如下代码:

function gen()
{
    $ret = (yield 'yield1');
    print_r('@@@@@' . $ret);
    echo '<br/>';

    $ret = (yield 'yield2');
    print_r('######' . $ret);
    echo '<br/>';
}

$gen = gen();

print_r('$$$$$$' . $gen->current());
echo '<br/>';

print_r('%%%%%%' . $gen->send('aaa'));
echo '<br/>';

print_r('&&&&' . $gen->send('bbb'));
echo '<br/>';

执行的结果是:

$$$$$$yield1
@@@@@aaa
%%%%%%yield2
######bbb
&&&&

对结果的分析:

1、首先:

//调用如下代码:
print_r('$$$$$$' . $gen->current());
echo '<br/>';

//输出的结果是:
$$$$$$yield1

调用current()方法,$gen->current(),将获取到第一个yield关键字(或者叫:yield表达式)后的值:yield1。到此,程序将暂停到这里,后面的程序不再执行。所以不会打印print_r('@@@@@' . $ret)这部分代码。

2、其次:

//调用如下代码:
print_r('%%%%%%' . $gen->send('aaa'));
echo '<br/>';

//输出的结果是:
@@@@@aaa
%%%%%%yield2

这里首先说下迭代器的send()方法:官方手册给出的解释是:

send()方法:向生成器中传入一个值,并且当做 yield 表达式的结果,然后继续执行生成器。
如果当这个方法被调用时,生成器不在 yield 表达式,那么在传入值之前,它会先运行到第一个 yield 表达式。
As such it is not necessary to "prime" PHP generators with a Generator::next() call (like it is done in Python).

当执行$gen->send('aaa')时,将向生成器中传入参数“aaa”,按照文档的说法,该参数将替换yield表达式,在这也就是 yield 'yield1'整体这部分 ,替换掉这部分后就变成了$ret='aaa';了,然后print($ret)的结果就是print('aaa');所以才会出现上面第一个:@@@@@aaa 。紧接着程序继续向下执行,遇到第二个yield关键字(这里说下send()方法,官方手册说了,执行send方法后,会自动调用current()方法,所以不用再手动调用了,所以才会有下面的参数"bbb"传递过去的时候,打印的结果不一样。相当于指针自动向前移动一位(我个人的理解)),遇到第二个yield关键字后,程序暂时停下来,程序返回该关键字后的数据,即:yield2,后面的程序将不再执行,所有会输出:%%%%%%yield2

3、第三步:

//调用如下代码:
print_r('&&&&' . $gen->send('bbb'));
echo '<br/>';

//输出的结果是:
######bbb
&&&&

这一步和第二步情况差不多。当执行了第二步的send()方法后,要记得:此时已经自动调用了current()方法了,也就是指针已经向前移动了一位了,所以,程序将在遇到下一个yield关键字后暂停。所以分析:因为第二步执行完了以后,执行到了$ret = (yield 'yield2');这里,遇到关键字yield后暂停了,所有,第三步将从该位置之后开始执行。当$gen->send('bbb')传递参数‘bbb’后,该参数将替换掉yield 'yield2'这部分内容,然后print_r('######' . $ret);这部分内容,然后后面没有数据了就只输出 print_r('&&&&' );这部分了

参考:https://blog.csdn.net/cs729298/article/details/72912008

猜你喜欢

转载自blog.csdn.net/shj_php/article/details/89156574