对一个数组进行遍历,例如foreach对数组进行遍历,但是如果数组的长度很大,利用该办法会占用很大的内存。
function range($start, $end, $step = 1) { $res = []; for ($i = $start; $i <= $end; $i += $step) { $res[] = $i; } return $res;}// 利用方法foreach (range(0, 9) as $key => $val) { echo $key, ' ', $val, \"大众\n\"大众;}
迭代器
迭代器即实现Iterator接口,即可迭代,即可以利用foreach语句进行遍历。利用迭代器实现遍历内存损耗远小于数组遍历,foreach迭代时,参数是一个实现Iterator接口的迭代器工具实例)。
class Xrange implements Iterator{ protected $start; protected $limit; protected $step; protected $current; public function __construct($start, $limit, $step = 1) { $this->start = $start; $this->limit = $limit; $this->step = $step; } public function rewind() { $this->current = $this->start; } public function next() { $this->current += $this->step; } public function current() { return $this->current; } public function key() { return $this->current + 1; } public function valid() { return $this->current <= $this->limit; }}// 利用方法foreach (new Xrange(0, 9) as $key => $val) { echo $key, ' ', $val, \"大众\n\公众;}
天生器
比较迭代器,天生器供应了一种更大略的办法来实现大略的工具迭代,利用天生器实现(天生器的灵魂在于yield,天生器天生的是一个Generator工具实例,该工具继续了Iterator接口。可以看出和迭代器类似)。 下例中函数xrange返回的是一个Generator工具,对该工具遍历时会遵照yield的特性,第一次迭代时,实行 $i = 0、$i < $limit、yield 返回 1 0,然后中断,第二次迭代时,实行$i += $step、$i < $limit, yield返回2 1,然后中断,以此类推。。。
function xrange($start, $limit, $step = 1) { for ($i = 0; $i < $limit; $i += $step) { yield $i + 1 => $i; }}foreach (xrange(0, 9) as $key => $val) { printf(\"大众%d %d \n\公众, $key, $val);}天生器的特性
天生器为可中断函数
如上例
值可通报
方法printer()返回的是一个Generarot工具,该工具有一个send()方法,可以通报参数。
function printer(){ while (true) { printf(\公众receive: %s\n\"大众, yield); }}$printer = printer();$printer->send('hello');$printer->send('world');// 输出receive: helloreceive: world
双向通信
可以在两个层级间(主函数代码片段、yield代码片段)实现可以通报参数,也能吸收结果。
function gen() { $ret = (yield 'yield1'); var_dump($ret); $ret = (yield 'yield2'); var_dump($ret);}$gen = gen();var_dump($gen->current()); // string(6) \"大众yield1\"大众var_dump($gen->send('ret1')); // string(4) \"大众ret1\公众 (第一个 var_dump) // string(6) \"大众yield2\"大众 (连续实行到第二个 yield,吐出了返回值)var_dump($gen->send('ret2')); // string(4) \公众ret2\"大众 (第二个 var_dump) // NULL (var_dump 之后没有其他语句,以是这次 ->send() 的返回值为 null)总结
yield关键字不仅可用于迭代数据,也由于它的双向通信,可用于协程在php措辞中的实现,必须清楚的是yield是天生器里面的关键字,协程能够利用天生器来实现,是由于天生器可以双向通信,当然协程也可以利用其他的办法实现,例如swoole的协程实现办法。(关于协程暂时不多说,该篇文章紧张先容的是yield关键字,即天生器),关于更多的天生器示例可以google。
参考http://www.codeceo.com/article/php-principle-of-association.htmlhttps://www.php.net/manual/en/class.iterator.phphttps://www.php.net/manual/en/language.generators.syntax.phphttps://www.php.net/manual/en/class.generator.phphttps://stackoverflow.com/questions/17483806/what-does-yield-mean-in-php