如何传入空生成器参数?

2022-08-30 21:05:23

我有一个方法,它采用生成器加上一些附加参数并返回一个新的生成器:

function merge(\Generator $carry, array $additional)
{
    foreach ( $carry as $item ) {
        yield $item;
    }
    foreach ( $additional as $item ) {
        yield $item;
    }
}

此函数的常用用例类似于:

function source()
{
    for ( $i = 0; $i < 3; $i++ ) {
        yield $i;
    }
}

foreach ( merge(source(), [4, 5]) as $item ) {
    var_dump($item);
}

但问题是,有时我需要将空源传递给该方法。理想情况下,我希望能够做这样的事情:merge

merge(\Generator::getEmpty(), [4, 5]);

这正是我在C#中所做的(有一个属性)。但我在手册中没有看到任何类型的生成器。IEnumerable<T>.Emptyempty

我已经设法通过使用这个函数来解决这个问题(现在):

function sourceEmpty()
{
    if ( false ) {
        yield;
    }
}

这很有效。代码:

foreach ( merge(sourceEmpty(), [4, 5]) as $item ) {
    var_dump($item);
}

正确输出:

int(4)
int(5)

但这显然不是一个理想的解决方案。将空生成器传递给该方法的正确方法是什么?merge


答案 1

有点晚了,但我自己需要一个空的生成器,并意识到创建一个实际上很容易......

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

不知道这是否比使用 更好,但这样你至少可以获得与非空生成器完全相同的类型。EmptyIterator


答案 2

只是为了完整性,也许是迄今为止最不冗长的答案:

function generator() {
    return; yield;
}

我只是想知道同样的问题,并记得文档中的早期描述(至少在语义上直到今天)生成器函数是任何带有关键字的函数。yield

现在,当函数在生成之前返回时,生成器应为空。

事实也的确如此。

3v4l.org 示例:https://3v4l.org/iqaIY


推荐