在C#中使用lambda表达式或匿名方法时,我们必须警惕对修改后的闭包陷阱的访问.例如:
foreach (var s in strings)
{
query = query.Where(i => i.Prop == s); // access to modified closure
...
}
Run Code Online (Sandbox Code Playgroud)
由于修改后的闭包,上面的代码将导致Where查询中的所有子句都基于最终值s.
正如这里所解释的那样,这是因为上面循环中s声明的变量foreach在编译器中被翻译成这样:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
Run Code Online (Sandbox Code Playgroud)
而不是像这样:
while (enumerator.MoveNext())
{
string s;
s = enumerator.Current;
...
}
Run Code Online (Sandbox Code Playgroud)
正如这里所指出的,在循环外声明变量没有性能优势,在正常情况下,我能想到这样做的唯一原因是你计划在循环范围之外使用变量:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
var finalString = s;
Run Code Online (Sandbox Code Playgroud)
但是,foreach循环中定义的变量不能在循环外使用: …
我只是喜欢JavaScript.这是如此优雅(想象一下在背景中叹息的爱情狂热的声音).
所以,最近我通过löve2d框架玩了Lua (很好!) - 我认为Lua也很棒.他们看待它,这两种语言非常相似.
有明显的差异,比如
但哪些是更微妙的?JavaScript编码器是否会认为在Lua中工作的东西略有不同?是否有任何陷阱对于有经验的编程人员尝试另一种语言而言可能并不明显?
例如:在Lua中,数组和散列不是分开的(只有表格) - 在JavaScript中,它们是数字数组和散列对象.嗯,这是一个比较明显的差异.
但是在变量范围,不变性或类似的东西方面是否存在差异?
我只是写了一些快速代码并注意到这个编译器错误
在lambda表达式中使用迭代变量可能会产生意外结果.
相反,在循环中创建一个局部变量并为其分配迭代变量的值.
我知道这意味着什么,我可以很容易地解决它,而不是什么大不了的事.
但我想知道为什么在lambda中使用迭代变量是个坏主意?
我以后可能会遇到什么问题?