Lambda 表达式和循环迭代变量:一个潜在的陷阱
通常不鼓励在 lambda 表达式中直接使用循环迭代变量。 由于 lambda 表达式处理变量捕获的方式,这种做法可能会产生意想不到的结果。
Lambda 表达式捕获对变量的引用,而不是捕获时的值。 因此,当循环迭代时,循环内创建的 lambda 表达式都会引用相同的、不断变化的迭代变量。 这导致所有 lambda 在循环完成后最终使用变量的 final 值,而不是创建每个 lambda 时的值。
让我们用 VB.NET 示例来说明这一点:
<code class="language-vb.net">Dim actions = new List(Of Action)() For i As Integer = 0 To 9 actions.Add(New Action(Function() Console.WriteLine(i))) Next For Each action As Action In actions action() End For</code>
您可能期望它打印 0 到 9。相反,它打印 10 十次!这是因为 Action
列表中的每个 actions
都引用相同的 i
,并且当第二个循环执行时,i
已经达到其最终值 10。
当循环体具有影响 lambda 表达式引用的变量的副作用时,问题就会放大。 这可能会导致难以调试的不一致。
解决方案:创建本地副本
为了防止这种情况发生,请在循环内创建迭代变量的本地副本:
<code class="language-vb.net">Dim actions = new List(Of Action)() For i As Integer = 0 To 9 Dim localI As Integer = i ' Create a local copy actions.Add(New Action(Function() Console.WriteLine(localI))) Next For Each action As Action In actions action() End For</code>
现在,每个 lambda 表达式都会捕获一个唯一的 localI
变量,并在创建时保存其值。 输出将正确地为 0 到 9。这个简单的更改可确保每个 lambda 使用其自己的独立值进行操作,避免意外行为。
以上是为什么循环中的 Lambda 表达式会产生意外结果?的详细内容。更多信息请关注PHP中文网其他相关文章!