我遇到了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"
这是正确的行为吗?
答案 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.很明显,它根本不像数组。它只产生一对值,但它们根本不是数组的一部分,因此不会进行重复数据删除。此外,生成器在被要求时仅产生下一个值,否则上述将导致无限循环。