Заводская функция не может вернуть локальный итератор для цикла for в lua?

Почему не работает заводская функция fromto вернуть локальную функцию iter как итератор цикла for?

function fromto(from,to)
    return iter,to,from-1
end

local function iter(to,from)--parameter:invariant state, control variable
    from = from + 1
    if from <= to then
        return from
    else
        return nil
    end
end

for i in fromto(1,10) do
    print(i)
end

2 ответа

Решение

Как говорит @YuHao, ваша схема может работать. Есть несколько способов изменить код. Вот один из них:

local function fromto(from,to)
    --parameter:invariant state, control variable
    local function iter(to,from)
        from = from + 1
        if from <= to then
            return from
        else
            return nil
        end
    end

    return iter,to,from-1
end


for i in fromto(1,10) do
    print(i)
end

Необходимо понимать две вещи: область видимости переменной и функции являются значениями.

  1. Переменные являются глобальными или локальными. Локальные переменные имеют лексическую область видимости. Они находятся в области видимости от оператора, следующего за их объявлением, до конца блока. Если имя не является именем локальной переменной, оно становится ссылкой на глобальную переменную. На вашей линии 2, iter это глобальная переменная.

  2. Функции не объявлены, они являются значениями, созданными при выполнении выражения определения функции. (Оператор определения функции - это просто альтернативный синтаксис для выражения определения функции и присвоения переменной.) Кроме того, функции не имеют имен. На них просто ссылаются одна или несколько переменных. Таким образом, значение вашей функции существует и на него ссылаются iter переменная, пока контроль выполнения не пройдет через строки, которые содержат определение функции. В вашем коде это конец строки 11.

Функция фабрики / итератора реализована правильно. Проблема заключается в использовании

local function iter(to,from)
  --...
end

эквивалентно:

local iter = function(to,from)
  --...
end

iter это локальная переменная, которая fromto не имеет доступа к. Удалить local и он побежит.

Другие вопросы по тегам