为啥我不能在“foreach”循环中取消设置变量?

Posted

技术标签:

【中文标题】为啥我不能在“foreach”循环中取消设置变量?【英文标题】:Why can't I unset a variable in a `foreach` loop?为什么我不能在“foreach”循环中取消设置变量? 【发布时间】:2012-06-29 23:56:59 【问题描述】:

为什么我不能在 foreach 循环中取消设置变量?

<?php

$array = array(a,s,d,f,g,h,j,k,l);

foreach($array as $i => $a)
 unset($array[1]);
 echo $a . "\n";


print_r($array);

在the code 中,变量在foreach 循环内的范围内,但在循环外未设置。是否可以在循环内取消设置?

【问题讨论】:

在几乎所有编程语言中,在迭代集合的同时修改集合是个坏主意。 我记得你需要通过 ref 设置数组:foreach(&amp;$array as $i =&gt; $a) Unset an array element inside a foreach loop的可能重复 Unset array element inside a foreach loop的可能重复 Accepted answer here is a proper explanation of what's actually happening and why。简而言之,foreach 就是 Copy-on-Write。 【参考方案1】:

你需要通过引用传递数组,像这样:

foreach($array as $i => &$a)

注意添加的&amp;。这在foreach的手册中也有说明:

为了能够在循环内直接修改数组元素 在 $value 之前加上 &。在这种情况下,该值将由 参考。

现在是produces:

a
d
f
g
h
j
k
l
Array
(
    [0] => a
    [2] => d
    [3] => f
    [4] => g
    [5] => h
    [6] => j
    [7] => k
    [8] => l
)

【讨论】:

【参考方案2】:

foreach 在数组的副本上执行,而不是在引用上执行,以便在执行期间更容易处理数组中更剧烈的更改(例如您的)。

【讨论】:

【参考方案3】:

foreach 在访问循环内的代码块之前迭代数组并将键分配给 $i 并将值分配给 $a。该数组实际上是在被迭代之前被函数“复制”的,因此对原始数组的任何更改都不会影响循环的进行。

您还可以使用 $i =&gt; &amp;$a 将 $array 通过引用传递到 foreach 中,而不是按值传递,这将允许数组的突变。

另一种选择是直接在数组上工作,你会看到不同的东西:

for($x=0;$x<count($array);$x++)
    unset($array[1]);
    // for $x=1 this would result in an error as key does not exist now
    echo $array[$x];


print_r($array);

当然,这假设您的数组是按数字顺序键控的。

【讨论】:

以上是关于为啥我不能在“foreach”循环中取消设置变量?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我需要在 foreach 循环后取消设置 $value

Java中foreach为啥不能给数组赋值

PHP - 在foreach循环中取消设置数组元素[重复]

在 C# 中,为啥我不能在 foreach 循环中修改值类型实例的成员?

为啥我不能访问这个数组 ForEach 循环中的数据? SwiftUI

为啥我不能使用 foreach 循环更新数组中的数据?