闭包中不允许使用可变值,但 for .. in
表达式可以。在 C# 中,for 循环更新迭代器,但在 F# 中却不像看起来那样。如何以及为何?
最佳答案
F# 的 for .. in
相当于 C# 的 foreach
循环,而不是 C# 的 for
循环。从 C# 5 开始,foreach
循环不会更新迭代器;相反,它会为循环中的每次迭代创建一个新变量(这对闭包有重要影响;有关详细信息,请参阅 Foreach now captures variables! (Access to modified closure)。这也是 F# 所做的:如果您编写
for txt in ["abc"; "def"; "ghi"] do
printfn "%s" txt
那么当您运行该循环时,您实际上创建了三个个新字符串变量,而不仅仅是一个。
为了向自己证明 F# 每次都会创建一个新变量,请尝试以下功能不太强大的代码:
let actions = new System.Collections.Generic.List<System.Action<unit>>()
for txt in ["abc"; "def"; "ghi"] do
actions.Add(fun () -> printf "%s " txt)
for action in actions do
action.Invoke()
如果 txt
每次通过 for .. in
循环都是相同的变量,这将打印 ghi ghi ghi
,就像 C# 一样4 及更早版本会有 -- 因为匿名函数关闭了变量,并且在循环之后变量包含 ghi
。但如果您运行上面的代码,您会看到它打印 abc def ghi
,就像 C# 5 及更高版本所做的那样。
所以你的问题的答案是 F# 允许在闭包中使用 for .. in
因为它实际上并没有改变任何东西。
关于for-loop - 为什么闭包中允许使用 'for .. in'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38499991/