php生成器

基本概念

  • 生成器在许多主流语言中都有,在php中配合协程的概念更是让很多人熟知,但由于这里只是一些想法,实际应用比较复杂,以我的水平还是听听算了,但是生成器以及相关的迭代器却相反,应用比较广泛
  • 如同下面的代码示例,generator可以节省大量资源(内存)
  • yield关键字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
function xrange ( $start , $limit , $step = 1 ) {
if ( $start < $limit ) {
if ( $step <= 0 ) {
throw new LogicException ( 'Step must be +ve' );
}

for ( $i = $start ; $i <= $limit ; $i += $step ) {
yield $i ;
}
} else {
if ( $step >= 0 ) {
throw new LogicException ( 'Step must be -ve' );
}

for ( $i = $start ; $i >= $limit ; $i += $step ) {
yield $i ;
}
}
}


foreach ( xrange ( 1 , 9 , 2 ) as $number ) {
echo " $number " ;
}

如同return的用法,yield会返回一个值给循环调用此生成器的代码并暂停执行生成器函数.

另外,一个生成器被第一次调用的时候会返回一个内部Generator类对象,此迭代器只能向前迭代且有个send的特殊方法: 将传入的值作为yield表达式的结果并且恢复发生器的执行


分割线之后浅谈ES6

1
2
3
4
5
6
7
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}

var hw = helloWorldGenerator();

上面代码来自阮老师博客,关键点是function后面的*号以及yield。和php中的迭代一样,这里只有调用next方法才会执行内部的代码块,同时返回值是一个对象{value:'xxx', done: false}value是当前yield语句的值,done表示遍历是否结束

对比php中的生成器,它还有的特点是:

  1. next方法可以带一个参数,作为上一个yield语句的返回值。
  2. for...of可以自动遍历Generator函数并不需调用next方法
  3. throw方法可以在函数体外抛出错误,函数体内捕获
  4. return方法返回给定的值并终结遍历
  5. js中也有协程概念,这样应用场景就有异步操作的同步化表达;控制流管理;部署iterator接口;用作数据结构