#iterator #lua #language-design
#итератор #lua #язык-дизайн
Вопрос:
В справочном руководстве Lua 5.1 указано, что итератор
for var_1, ···, var_n in explist do block end
эквивалентно коду:
do
local f, s, var = explist
while true do
local var_1, ···, var_n = f(s, var)
var = var_1
if var == nil then break end
block
end
end
Почему Lua требует переменную ‘state’, s?
Я бы предположил, что это означает, что функции-итератору не обязательно переносить какое-либо состояние для каждого итератора (см., Например, Дизайн функции, производящей итератор ipairs), однако довольно просто создавать замыкания по требованию, которые переносят это состояние, и затраты в значительной степени составляют один раз за итерацию, основанный на эффективности случай для меня не так ясен.
Ответ №1:
Потому что тройная конструкция не мешает вам использовать замыкание, в то время как альтернативный подход не позволяет вам не использовать замыкания. Иногда дизайн внешнего состояния является более простым подходом.
Например, предположим, что вы используете for
цикл для перебора страниц, которые нужно отобразить в ответе на запрос RESTful. С помощью циклов, основанных на внешнем состоянии, вы можете написать функцию, которая выполняет итерацию страниц на основе таблицы, представляющей параметры запроса, отображающие состояние (которые вы создаете из URL один раз и повторно используете для нескольких других функций). С помощью triples вы можете выполнять итерации только с этими значениями, не будучи вынужденным переносить их (и любую другую подобную функцию) в конструктор замыкания.
Комментарии:
1. Совершенно случайно я заметил, что в руководстве 5.2 есть раздел «Итераторы без состояния», в котором говорится, что цель разработки именно в этом, чтобы избежать затрат на создание новых замыканий (стр. 59). Так что это действительно правильный ответ. Я немного удивлен этим, согласно моим рассуждениям в вопросе, но я думаю, вы можете придумать тесты, в которых эта стоимость доминирует.
2. Это не только с точки зрения производительности. Иногда создание замыкания просто усложняет код.
Ответ №2:
Почему нет? Что хорошего в том, чтобы сделать это каким-то другим способом? Как говорят в Microsoft, каждая идея что-то изменить начинается с минус 100 баллов.
Комментарии:
1. Это не более простая семантика: идея о том, что элемент var является начальной точкой, а f сообщает вам, как перейти к следующей точке из любой точки, — это способ, который я чаще всего видел для представления итераторов. Итак, я предполагаю, что парная семантика рассматривалась наряду с тройной семантикой и не понесла штрафа -100.
2. Что ж, единственный человек, который может ответить на этот вопрос окончательно, вероятно, изобретатель Lua.