PHP generator Generator understanding

不言
Release: 2023-03-24 07:26:02
Original
1454 people have browsed it

The content introduced in this article is about the understanding of PHP Generator. It has a certain reference value. Now I share it with everyone. Friends in need can refer to it.

Reprinted and compiled from: Jifan, Fengxue Zhiyu, PHP manual

Generator

  • ##Solved problems


Quoted from the official website: Generators provide an easier way to implement simple object iteration. Compared with the way of defining a class to implement the Iterator interface, the performance overhead and complexity are greatly reduced. Generators allow you to write code in a foreach block to iterate over a set of data without creating an array in memory, which would hit your memory limit (emphasis added) or take up considerable processing time. Instead, you can write a generator function, just like a normal custom function, and instead of a normal function returning only once, the generator can yield as many times as needed in order to generate the values ​​that need to be iterated over.


  • Generate implements the Iterator interface

  • <?php
    //生成器
    Generator implements Iterator {
        //返回当前产生的值
        public mixed current ( void )
        //返回当前产生的键
        public mixed key ( void )
        //生成器继续执行
        public void next ( void )
        //重置迭代器,如果迭代已经开始了,这里会抛出一个异常。
        public void rewind ( void )
        //向生成器中传入一个值,当前yield接收值,然后继续执行下一个yield
        public mixed send ( mixed $value )
        //向生成器中抛入一个异常
        public void throw ( Exception $exception )
        //检查迭代器是否被关闭,已被关闭返回 FALSE,否则返回 TRUE
        public bool valid ( void )
        //序列化回调
        public void __wakeup ( void )
        //返回generator函数的返回值,PHP version 7+
        public mixed getReturn ( void )
    }
    ?>
    Copy after login
  • Keyword yield

The core of the generator function is the yield keyword. In its simplest form, it looks like a return statement, except that a normal return returns a value and terminates the execution of the function, while yield returns a value to the code that loops through the generator and simply pauses the execution of the generator function. A generator cannot return a value: doing so will generate a compilation error. However return null is valid syntax and will terminate the generator execution.



Yield can only be used in functions, otherwise it will report PHP Fatal error: The "yield" expression can only be used inside a function, whenever yield is used All keyword functions will return a Generator object. Each time the code is executed to the yield statement, execution will be suspended and the value of the expression in the yield statement will be returned to the Generator object. When continuing to iterate the Generator object, the code after yield will continue to be executed until all yield statements are executed or there is a return statement. This The renturn statement can only return null, that is, return;, otherwise a compilation error will occur.

  • Understand the execution process and available functions based on examples

1 Example 1

<?php
function xrang($start, $end, $step=1){
    for($i=$start; $i<=$end; $i += $step) {
        yield $i;  //yield关键字定义了中断点
    }   
}


//foreach (xrang(1, 10000) as $num) {
//  echo $num."\n"; 
//}


$rang = xrang(1,2);
var_dump($rang).PHP_EOL; //输出: object(Generator)#1 (0) {}
var_dump($rang instanceof Iterator).PHP_EOL; //输出: bool(true)


$key = $rang->key(); 
var_dump("key: ".$key).PHP_EOL; //输出: string(6) "key: 0"
$valid = $rang->valid();
var_dump("valid: ".$valid).PHP_EOL; //输出: string(8) "valid: 1"
$current = $rang->current();
var_dump("current: ".$current).PHP_EOL; //输出: string(10) "current: 1"


$rang->next();


$key = $rang->key(); 
var_dump("key: ".$key).PHP_EOL; //输出: string(6) "key: 1"
$valid = $rang->valid();
var_dump("valid: ".$valid).PHP_EOL; //输出: string(8) "valid: 1"
$current = $rang->current();
var_dump("current: ".$current).PHP_EOL; //输出: string(10) "current: 2"


$rang->next();


$key = $rang->key();
var_dump("key: ".$key).PHP_EOL; //输出: string(5) "key: "
$valid = $rang->valid();
var_dump("valid: ".$valid).PHP_EOL; //输出: string(7) "valid: "


//$rang->rewind(); //重置,目前看到的所有文档中,rewind()仅在第一次调用Generator的时候隐式执行。生成器开始迭代后调用会抛出Fatal error。
?>
Copy after login

2 Example 2


<?php
function gen(){
    echo "1111\n";
    $ret = (yield &#39;yield1&#39;);
    var_dump($ret);
    echo "2222\n";
    $ret = (yield &#39;yield2&#39;);
    var_dump($ret);
    //return;
}
$gen = gen();
var_dump($gen->current()).PHP_EOL;
$a = $gen->send(&#39;ret1&#39;);
echo "66666\n";
var_dump($a).PHP_EOL;
echo "77777\n";
var_dump($gen->valid()).PHP_EOL;
$b = $gen->send(&#39;ret2&#39;);
var_dump($b).PHP_EOL;
var_dump($gen->valid()).PHP_EOL;


//1111
//string(6) "yield1"
//string(4) "ret1"
//2222
//66666
//string(6) "yield2"
//77777
//bool(true)
//string(4) "ret2"
//NULL
//bool(false)
?>
Copy after login

    2.1 执行过程为:

        1.首先调用gen(),进入函数输出1111,执行到第一个yield关键字所在的位置中断(此时yield表达式的值为定义的"yield1",使用current()获取当前表达式的值即得到string(6) "yield1")
        2.调用send()方法向生成器中传入值"ret1"(传入生成器的值.这个值将会被作为生成器当前所在的 yield 的返回值),此时生成器从当前所在的yield表达式开始迭代,程序继续往下执行   
        3.遇到var_dump输出当前表达式的值"ret1",继续执行输出2222
        4.继续执行,程序来到第二个yield中断点,此时表达式的值为定义值"yield2",因为调用的是send()方法,该方法返回当前所在的yield的值(current()方法值)。(查看send方法的官方文档)
        5.$a获取到send方法的返回值即"yield2",继续执行输出"66666", $a, "77777"
        6.输出当前生成器是否可用
        7.继续执行,向生成器中传入值"ret2",生成器开始继续迭代。此时生成器位于第二个yield表达式,该表达式接受"ret2"作为返回值赋予变量$ret,打印得到string(4) "ret2"。
        8.打印之后,$b == NULL,为NULL的原因因为未彻底理解清楚(疑问之处在于此时的send()方法到底有没有返回NULL),猜测可能有如下两个原因:
            8.1 一者可能是因为生成器之后没有中断点,也没有返回值(返回值不被允许,或者说仅允许返回return; return;用于终止生成器的执行),$gen->send()方法根本就没有返回任何东西,导致$b == NULL
           8.2 二者可能是$gen->send('ret2')传入值后,生成器迭代完本次的yield,隐式调用了next()和current(),又因为next()下面没有yield中断点使得current()返回NULL,导致send()返回值为NULL
             8.3 根据上下文,二的可能性更大


    2.2 关于send()方法
        send()向生成器中传入一个值,并且当做 yield 表达式的结果,然后继续执行生成器。如果当这个方法被调用时,生成器不在 yield 表达式,那么在传入值之前,它会先运行到第一个 yield 表达式。            

相关推荐:

PHP生成器的功能与用法详解

php生成器详细介绍

The above is the detailed content of PHP generator Generator understanding. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!