How to yield empty generator?

半城伤御伤魂 提交于 2019-12-01 02:58:03

Bit late, but needed an empty generator myself, and realized creating one is actually quite easy...

function empty_generator(): Generator
{
    yield from [];
}

Don't know if that's better than using the EmptyIterator, but this way you get exactly the same type as non-empty generators at least.

I've found the solution:

Since \Generator extends \Iterator I can just change the method signature to this:

function merge(\Iterator $carry, array $additional) 
{
    // ...

This is input covariance thus it would break backward compatibility, but only if someone did extend the merge method. Any invocations will still work.

Now I can invoke the method with PHP's native EmtpyIterator:

merge(new \EmptyIterator, [4, 5]);

And the usual generator also works:

merge(source(), [4, 5])

Just for completeness, perhaps the least verbose answer so far:

function generator() {
    return; yield;
}

I just wondered about the same question and remembered an early description in the docs (which should be in at least semantically until today) that a generator function is any function with the yield keyword.

Now when the function returns before it yields, the generator should be empty.

And so it is.

Example on 3v4l.org: https://3v4l.org/iqaIY

As explained in the official docs, you can create an in-line Generator instance, by using yield in an expression:

$empty = (yield);

That should work, but when I tried using that, I got a fatal error (yield expression can only be used in a function). Using null didn't help either:

$empty = (yield null); //error

So I guess you're stuck with the sourceEmpty function... it was the only thing I found that works... note that it will create a null value in the array you're iterating.
All the code was tested on PHP 5.5.9, BTW

The best fix I can come up with (seeing as compatibility is an issue) would be to make both arguments optional:

function merge(\Generator $carry = null, array $additional = array())
{
    if ($carry)
        foreach ($carry as $item)
            yield $item;
    foreach ($additional as $item)
        yield $item;
}
foreach(merge(null, [1,2]) as $item)
    var_dump($item);

This way, existing code won't brake, and instead of constructing an empty generator, passing null will work just fine, too.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!