为什么'会产生'不会覆盖PHP中的键值对?

时间:2015-10-23 13:49:26

标签: php generator yield

我遇到了Generators的这种奇怪的行为,这在PHP手册中没有描述。

我有两个foreach循环 - 第一个设置一些默认值,第二个覆盖它们。但由于缺少一些关键:值对,我无法使用array_merge(),因此我尝试使用Generators来实现此目的。

我发现即使docs say

,关联数组也会覆盖yield键
  

产生键/值对的语法与用于定义关联数组的语法非常相似,如下所示。

示例:

Array
(
    [01.05] => Array
        (
            [0] => 17:30
            [1] => 20:30
        )

    [01.06] => Array
        (
            [0] => 20:30
            [1] => 21:30
        )

    [01.07] => Array
        (
            [0] => 20:30
        )

)

结果

function yieldTest()
{
    // those are array values (in my code - taken from data source; here static example)
    $arr1 = ['a' => 1, 'b' => 2, 'c' => 3];
    $arr2 = ['b' => 'B', 'd' => 'D'];

    // 1st loop
    foreach ($arr1 as $k => $v) {
        yield $k => $v;
    }

    // 2nd loop
    foreach ($arr2 as $k => $v) {
        yield $k=>$v;
    }
}

foreach(yieldTest() as $k=>$v) {
    var_dump($k . ' = ' . $v) . "\n";
}

所以钥匙已经被淹没了。我期待获得以下输出:

string(5) "a = 1"
string(5) "b = 2"
string(5) "c = 3"
string(5) "b = B"
string(5) "d = D"

这是正确的行为吗?

1 个答案:

答案 0 :(得分:3)

生成器不是关联数组。它表示" [t] 语法用于产生键/值对非常类似于[...]关联数组" ;它根本没有说发生器的行为就像一个关联数组。

事实上,不能表现相同且重复数据删除的密钥,因为密钥并非一次全部都知道。每个密钥都在需要时生成 ,而不是之前。循环生成器的foreach语法实际上是语法糖:

function foo() {
    while (true) {
        yield mt_rand(1, 2) => 'foo';
    }
}

$foo = foo();
$foo->next();
echo $foo->key(), ' => ', $foo->current(), PHP_EOL;
$foo->next();
echo $foo->key(), ' => ', $foo->current(), PHP_EOL;
$foo->next();
echo $foo->key(), ' => ', $foo->current(), PHP_EOL;
$foo->next();
echo $foo->key(), ' => ', $foo->current(), PHP_EOL;

This will yield the same key many times, unpredictably.很明显,它根本不像数组。它只产生一对值,但它们根本不是数组的一部分,因此不会进行重复数据删除。此外,生成器在被要求时仅产生下一个值,否则上述将导致无限循环。