Lambda表达式提供了一种在循环中定义内联函数的简洁方法。但是,直接在lambda中使用迭代变量可能会导致以后出现意外行为。
迭代变量的Lambda陷阱:
考虑以下代码:
<code class="language-c#">for (int i = 0; i < 10; i++) { Action action = () => Console.WriteLine(i); actions.Add(action); } foreach (var action in actions) { action(); }</code>
人们可能会认为每个lambda都会打印i的相应值。但是,由于闭包,所有lambda都共享对i的相同捕获引用。
意外的打印结果:
当循环退出时,i变为10,所有lambda现在都指向此最终值。结果,执行lambda将打印十次“10”,而不是预期的从0到9的序列。
这种行为源于lambda闭包维护对其作用域内声明的变量的引用,即使循环已完成也是如此。
避免方法和替代方法:
为了解决这个问题,在循环中创建一个局部变量,并为其赋值迭代变量的值:
<code class="language-c#">for (int i = 0; i < 10; i++) { int j = i; // 创建一个局部变量 Action action = () => Console.WriteLine(j); actions.Add(action); } foreach (var action in actions) { action(); }</code>
这确保每个lambda捕获j的不同值,从而产生预期的打印序列。
请记住,直接在lambda表达式中使用迭代变量可能会导致与闭包相关的意外情况。相反,考虑创建局部变量以准确捕获所需的值。
以上是为什么 Lambda 表达式会捕获迭代变量的最终值,如何避免这种情况?的详细内容。更多信息请关注PHP中文网其他相关文章!