Q1:次の??
場合は何もしないと思います。
$a = [1, 2];
foreach ($a ?? [] as &$v) {
$v++;
}
var_dump($a);
しかし、なぜ?
array(2) {
[0]=>
int(1)
[1]=>
int(2)
}
Q2:これはもっと奇妙です:
foreach ($a = [1, 2] as &$v) {
$v++;
}
var_dump($a);
// output
array(2) {
[0]=>
int(1)
[1]=>
int(2)
}
私の考え:式は参照できないと思いますがforeach
、エラーをキャッチするか、何らかの方法でコピーを作成します。動作する参照:
$a = 1;
$c = &$a;
動作しない:
$a = 1;
$c = &($a);
$c = &($a ?? []);
$c = &($a + 1);
ドスは、??
コピーを作成しますか?ifがnullforeach
であるため、をラップしたくないので失敗します。if (isset($a))
$a
foreach
TL; DRあなたの場合、次のようにnull合体演算子を使用することを検討できます。
$a = $a ?? [];
foreach ($a as &$v) { ... }
または、array_map()
キーを使用するか、キーを使用して基になる配列を変更することにより、参照をまったく使用しないでください。
$a = [1, 2];
foreach ($a ?? [] as &$v) {
$v++;
}
var_dump($a);
合体演算子は元の配列のコピーを使用し、の場合は右側のオペランドを適用しnull
ます。したがって、反復は元の配列のコピーに対して行われます。
これを次のものと比較できます。
$a = [1, 2];
$x = $a ?? [];
$x[1] = 4;
var_dump($a); // [1, 2]
compiled vars: !0 = $a, !1 = $v
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
8 0 E > ASSIGN !0, <array>
9 1 COALESCE ~3 !0
2 QM_ASSIGN ~3 <array>
3 > FE_RESET_RW $4 ~3, ->8
... rest of looping code
の最初のオペランドFE_RESET_RW
は、繰り返されるハッシュ変数で~3
あり、!0
($a
コード内で)の代わりに、予想どおりに行われていることがわかります。
foreach ($a = [1, 2] as &$v) {
$v++;
}
ここで何が起こるかというと、割り当ての戻り値が$a = [1, 2]
反復する配列として使用されます。
この動作を次のようなものと比較できます。
$x = $a = [1, 2];
$x[0] = 4; // modify in-place
var_dump($a); // [1, 2]
compiled vars: !0 = $a, !1 = $v
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
3 0 E > ASSIGN $2 !0, <array>
1 > FE_RESET_RW $3 $2, ->6
... rest of looping code
繰り返しますが、$2
はFE_RESET_RW
割り当て結果であるの最初のオペランドであるため、!0
($a
コード内で)に対して反復は発生しません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加