Модифицированные значения не допускаются в замыканиях, но выражение for .. in
в порядке. В C# цикл for обновляет итератор, но не в F #, как кажется. Как и почему?Почему «для .. в» разрешено закрытие?
ответ
F 0's 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
в закрытии, потому что это на самом деле ничего не мутирует.
Отличный ответ, спасибо. – aikixd