上一次发了一篇关于闭包中间件的文章,只是略微提到一点皮毛(也只理解到了那么点皮毛)。php
将技术知识放到具体的应用场景中,才能更好的理解它。恰巧我前两天在对一个统计数据脚本进行升级优化时,算是对 “闭包” 进行了一点点小的应用吧,我后续会单独发一篇文章谈谈心得。html
今天,说说我学习yield
的一些小感觉吧。 网上关于yield
的示例最多的,就是一个xrange()
的实现吧。都烂大街了,我就不按这个套路来了......shell
来段小白代码闭包
function fini() {
$x = 'hello';
yield $x;
}
$res = fini();
echo $res->current(); // hello
复制代码
给小白观众说明一下吧。yield
关键字在这里和return
的做用有点像。函数
区别呢,就是它返回的是一个Generator
对象的实例,我这里调用的current()
就是它的方法之一。 也就是说,只要一个函数中有yield
,那么调用这个函数就会返回Generator
。列一下官网手册:学习
Generator implements Iterator {
/* 方法 */
public mixed current ( void )
public mixed key ( void )
public void next ( void )
public void rewind ( void )
public mixed send ( mixed $value )
public void throw ( Exception $exception )
public bool valid ( void )
public void __wakeup ( void )
}
复制代码
来段高级小白的代码优化
function fini() {
$x = 'hello';
$y = (yield $x); // [1]
echo $y; // [5]
}
$res = fini(); // [2]
echo $res->current(); // [3]
$res->send(' world'); // [4]
复制代码
接下就是yield
神奇的地方了,他会输出:spa
hello world
复制代码
让咱们来捋捋这段代码,看看到底发生了什么。指针
yield
会实例化一个Generator
对象(也就是[1]
),而且自动调用其rewind()
方法Generator
实例化赋值给$res
([2]
)current()
获取当前Generator
中存储(内部指针的位置)的值'hello'
并输出([3]
)send()
方法,使得程序回到了[1]
位置,而且把send()
方法的参数赋值给$y
并输出([5]
)多来几个yield
code
function fini() {
$x = 'hello';
$y = (yield $x);
echo $y;
yield ' world';
}
$res = fini();
echo $res->current();
$wes = $res->send(' big');
echo $wes;
复制代码
最终输出结果:
hello big wolrd
复制代码
我以为,yield
就是一把 “切肠刀”,把函数这根 “香肠” 切成n截,而后依次放到Generator
这个 “饭盒”,而后你须要 “吃” 的时候,拿出一截来,可是 “吃” 的时候只能按照放好的次序来 “吃”。
比喻可能有不当的地方,作抛砖引玉,但愿大佬来斧正。
最最后,安利一波鸟哥的《在PHP中使用协程实现多任务调度》,向大佬学习,收益颇多。