【问题标题】:who does PHP's YIELD->send() works?PHP 的 YIELD->send() 对谁有效?
【发布时间】:2013-11-15 22:26:23
【问题描述】:
function yielding()
{
    for ($i = 0; $i < 10; $i++) {
        var_dump(yield);
    }
}

$y = yielding();

foreach ($y as $val) {
    $y->send('foo');
}

输出:

string(3) "foo"
NULL
string(3) "foo"
NULL
string(3) "foo"
NULL
string(3) "foo"
NULL
string(3) "foo"

我预计输出是:10 次 string(3) "foo",但输出是 1 次 NULL 和 1 次 string(3) "foo"(9 次)。为什么? generator->send() 会跳过一次迭代吗?

【问题讨论】:

    标签: php yield


    【解决方案1】:

    yield 用于在生成器内部发送和接收值。来自Generator RFC如果没有发送任何内容(例如在 foreach 迭代期间),则返回 null

    所以在你的代码中,生成器被恢复了两次:

    1. 一次用于($y as $val) -- yield 在生成器内返回 null
    2. 一次用于$y-&gt;send('foo') -- yield 在生成器内返回“foo”

    当我运行你的代码时,我得到了 10 行输出,以 NULL 结尾

    string(3) "foo"
    NULL
    ...
    string(3) "foo"
    NULL
    

    【讨论】:

      【解决方案2】:

      函数send() is used to inject values
      如果您想打印 foo 十次,那么以下方法可能会起作用(未测试)

      function yielding()
      {
          for ($i = 0; $i < 10; $i++) {
      ////get a value from the caller
              $string = yield;
              echo $string;
          }
      }
      

      编辑:

      $y = yielding();
      
      for($k=0;$k<10;$k++)
          $y->send('foo');
      

      这将打印十次。

      迭代对象时会发生什么:(引自手册) "当你迭代那个对象时(例如,通过一个 foreach 循环),PHP 将在每次需要一个值时调用生成器函数,然后在生成器产生一个值时保存生成器的状态,以便它可以需要下一个值时恢复。

      一旦没有更多的值可以产生,那么生成器函数可以简单地退出,调用代码会继续,就像数组已经用完值一样。”

      【讨论】:

      • 是一样的。好倍“foo”而不是十倍。
      猜你喜欢
      • 2017-03-15
      • 2015-08-17
      • 2017-10-28
      • 1970-01-01
      • 1970-01-01
      • 2020-02-03
      • 2014-07-04
      • 2010-12-11
      • 2020-12-20
      相关资源
      最近更新 更多