Рассмотрим следующий код Lua:Какова правильная семантика замыкания по переменной цикла?
f = {}
for i = 1, 10 do
f[i] = function()
print(i .. " ")
end
end
for k = 1, 10 do
f[k]()
end
Это печатает числа от 1 до 10. В этом случае i
закрыта над значением для каждой итерации внешнего цикла. Это, как я всегда понимаемые затворы, и я был очень рад ...
... пока я не портирования некоторого Lua кода на C#, и я попытался сделать то же самое:
var f = new Action[10];
for (int i = 0; i < 10; i++)
{
f[i] = (new Action(delegate()
{
Console.Write(i + " ");
}));
}
for (int k = 0; k < 10; k++)
{
f[k]();
}
И теперь я получаю номер 10, напечатанный 10 раз (давайте забудем, что lua массивы основаны на 1). На самом деле происходит то, что в этом случае замыкание работает над переменной, а не ее значением, что имеет большой смысл, так как я вызываю функции только после завершения первого цикла.
JavaScript, кажется, имеет ту же семантику (близко над переменной):
var f = []
for (var i = 0; i < 10; i++)
{
f[i] = function()
{
document.write(i + ' ');
};
}
for (var k = 0; k < 10; k++)
{
f[k]();
}
На самом деле, оба поведения делают много смысла, но, конечно, несовместимы.
Если есть «правильный» способ сделать это, то либо lua, либо C# и JavaScript ошибочны (я еще не пробовал с другими языками). Поэтому мой вопрос: «Какова« правильная »семантика закрытия переменной внутри цикла?»
Редактировать: Я не спрашиваю, как «исправить» это. Я знаю, что я могу добавить локальную переменную внутри цикла и закрыть ее, чтобы получить поведение lua в C#/JavaScript. Я хочу знать, что является теоретически правильным значением закрытия над зацикленной переменной, и бонусные баллы для краткого списка того, какие языки реализуют замыкания по-своему.
Редактировать: Чтобы перефразировать мой вопрос: «Каково поведение закрытия зацикленной переменной в исчислении лямбда?»
Возможный дубликат [Почему плохо использовать переменную итерации в выражении лямбда] (http://stackoverflow.com/questions/227820/why-is-it-bad-to-use-a-iteration- variable-in-a-lambda-expression) –
JavaScript не имеет области действия блока, вам понадобится дополнительная функция. – Bergi
Почему вы думаете, что есть «правильный» способ? Это разные языки; ни один из них не является «неправильным». Они просто разные. –