Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/254.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中,“与”的区别是什么;return"&引用;收益率&引用;收益来自;在同一函数中混合收益率和收益率?_Php_Return_Generator_Yield - Fatal编程技术网

在PHP中,“与”的区别是什么;return"&引用;收益率&引用;收益来自;在同一函数中混合收益率和收益率?

在PHP中,“与”的区别是什么;return"&引用;收益率&引用;收益来自;在同一函数中混合收益率和收益率?,php,return,generator,yield,Php,Return,Generator,Yield,return和yield之间的区别似乎很明显,直到我发现也存在yield from以及将return和yield组合在同一个函数中的可能性 我对return的理解是之后的一切都没有执行,对吧 然而: function generate(): iterable { return [1, 2, 3]; } foreach (generate() as $value) { echo $value; } 生产:“123” 但以下几点: function generate(): ite

return
yield
之间的区别似乎很明显,直到我发现也存在
yield from
以及将
return
yield
组合在同一个函数中的可能性

我对
return
的理解是之后的一切都没有执行,对吧

然而:

function generate(): iterable {
    return [1, 2, 3];
}

foreach (generate() as $value) {
    echo $value;
}
生产:“123”

但以下几点:

function generate(): iterable {
    return [1, 2, 3];
    yield;
}

foreach (generate() as $value) {
    echo $value;
}
什么也不生产!那么这意味着收益率被执行了

这是一个bug吗?

来自:

任何包含
yield
的函数都是生成器函数

因此,无论是否执行
yield
,解析器都会在函数定义中的某个地方看到它,并将其转换为生成器

如果函数从不执行
yield
语句,则生成器不会生成任何值。当您尝试使用结果时,
return
返回的值将被忽略。文件说:

注意:
在PHP5中,生成器无法返回值:这样做将导致编译错误。空的
return
语句在生成器中是有效的语法,它将终止生成器。自PHP7.0以来,生成器可以返回值,这些值可以使用

所以你可以做:

$gen = generate();
foreach ($gen as $value) {
    echo $value;
}
print_r($gen->getReturn());
返回
只向调用者返回一个唯一的值

收益率
将当前函数/方法转换为返回a,它将产生不止一个唯一的值:每次触发
yield
时,它都会向调用者提供值,一次一个,传统上使用
foreach
循环

收益率
+
收益率
生成器除了生成值外,还可以提供唯一的返回值。该值不会成为生成器循环的一部分,必须使用方法访问它

收益
+
收益
这可能被视为一个bug,但事实并非如此

分为两个阶段:

  • 从代码到字节码:在此阶段,
    generate()
    函数被视为包含
    yield
    关键字,因此它被标记为生成
    生成器
  • 执行:由于
    返回
    恰好在
    产生
    之前,因此生成器没有机会产生任何值。但是,可以使用检索
    [1,2,3]
    数组
  • 完整的注释示例:
    //生成整数1和2
    函数generateIntegers1And2():生成器{
    yield 1;//
    var_dump(generate()->GetReturn());
    最后一个示例,返回“结束”函数执行,也就是说,代码没有达到yeld。
    // Generate integers 1 and 2
    function generateIntegers1And2(): Generator {
        yield 1;                                  // <--+   <--+   <--+
        yield 2;                                  //  <-+    <-+    <-+
    }                                             //    |      |      |
                                                  //    |      |      |
    foreach (generateIntegers1And2() as $value) { //    |      |      |
        var_dump($value); // Shows 1, then 2          ->*      |      |
    }                                                       // |      |
                                                            // |      |
    function generateOuterYield(): Generator {              // |      |
        // Yields the generator *itself* returned by           |      |
        // generateIntegers1And2() not the actual values       |      |
        // generated by it.                                    |      |
        // This means we are producing here a generator        |      |
        // of generator of integers.                           |      |
        yield generateIntegers1And2();          // <-+         |      |
    }                                             // |         |      |
                                                  // |         |      |
    foreach (generateOuterYield() as $value) {    // |         |      |
        var_dump($value);                       // ->*         |      |
        // The two levels of imbrication means we have         |      |
        // to loop once more to actually consume               |      |
        // generateIntegers1And2                               |      |
        foreach ($value as $val) {                          // |      |
            var_dump($val); // Shows 1, then 2               ->*      |
        }                                                          // |
    }                                                              // |
                                                                   // |
    // A generator can just be returned as-is:                        |
    function generateOuterReturn(): Generator {                    // |
        return generateIntegers1And2();                            // |
    }                                                              // |
                                                                   // |
    // it doesn't change the way it is consumed                       |
    foreach (generateOuterReturn() as $value) {                    // |
        var_dump($value); // Shows 1, then 2                          |
    }                                                              // |
                                                                   // |
    function generateOuterYieldFrom(): Generator {                 // |
        // First yield values generated by generateIntegers1And2()    |
        yield from generateIntegers1And2();                        // *<---+
        // then yield integers 3                                           |
        yield 3;                                                     // <--+
        // and 4                                                           |
        yield 4;                                                     //  <-+
    }                                                                //    |
                                                                     //    |
    foreach (generateOuterYieldFrom() as $value) {                   //    |
        var_dump($value); // Shows 1, 2, 3 and 4                         ->*
    }
    
    function generateIntegers56AndReturn(): Generator {
        yield 5;                                                  // <---+
        yield 6;                                                  //  <--+
                                                                  //     |
        return ["five", "six"];                       // <--+            |
    }                                                 //    |            |
                                                      //    |            |
    $gen = generateIntegers56AndReturn();             //    |            |
                                                      //    |            |
    // Consume the values **yielded** by                    |            |
    // generateIntegers56AndReturn()                        |            |
    foreach ($gen as $value) {                        //    |            |
        var_dump($value); // Shows 5, then 6                |          ->*
    }                                                 //    |
                                                      //    |
    // Access the value **returned** by the generator       |
    var_dump($gen->getReturn());                      //  ->*
    
    function wtf(): Generator {
        return ["W", "T", "F", "!"];
        // Without the following line, PHP would complain with a TypeError:
        // Return value of wtf() must be an instance of Generator, array returned.
        // The presence of a yield keyword anywhere inside the function makes it a Generator.
        // However, since we return *before* reaching any *yield*, 42 is never yielded.
        // This is empty generator!
        yield 42;
    }
    
    $gen = wtf();
    
    // This foreach loop is not entered!
    foreach ($gen as $value) {
        var_dump($value);
    }
    
    // However, we can loop on the array *returned* by wtf():
    foreach ($gen->getReturn() as $value) {
        echo $value; // Will print: WTF!
    }