带有递归迭代器的词法范围如何工作?

时间:2017-08-09 08:08:29

标签: recursion iterator lexical-scope

这个特殊的示例函数在Lua中,但我认为主要概念适用于任何具有词法作用域,第一类函数和迭代器的语言。

代码说明(TL; DR - 见代码):

下面的代码定义了一个迭代器构造函数,它只定义了一个局部值并返回一个迭代器函数。

此迭代器函数在运行时使用构造函数中的本地值并将该值增加1.然后递归运行,直到值达到5,然后将值加1并返回数字5.如果它运行再次,它会递归地运行,直到值达到20或更高,然后它返回nil,这是循环停止的信号。

然后我使用构造函数提供的迭代器运行外部循环,当迭代器返回值(5)时,它将运行循环体。在外部循环的主体中,我放置了一个内部循环,它也使用了构造函数提供的迭代器。

程序应该运行一次循环体(当外循环迭代器中的值达到5时),然后完全运行内循环(让内循环值达到20),然后返回外循环运行它直到它完成。

    function iterConstr()
        local indexes = {0}
        function iter()
            print(indexes[1])
            indexes[1] = indexes[1] + 1
            if indexes[1] == 5 then
                indexes[1] = indexes[1] + 1
                return 5
            elseif indexes[1]>=21 then
                print("finished!")
                return nil
            else
                print("returning next one")
                return iter()
            end
        end
        return iter
    end

    for val in iterConstr() do
        for newVal in iterConstr() do

        end
        print("big switch")
    end

我没想到的行为是内循环和外循环的值似乎是连在一起的。当焦点在通过内部循环后返回到外部循环时,它将以外部循环(6)的预期下一个值运行,但随后不是迭代并递增到20,而是立即跳转到21,这是内循环结束的地方!

任何人都可以帮助解释为什么会出现这种奇怪的行为吗?

1 个答案:

答案 0 :(得分:1)

我相信你的问题出在第3行 - 你将iter声明为全局函数而不是本地函数,这使得它可以从任何Lua块中访问。将该行更改为local function iter()会更正此行为。因此,我认为对于应用词汇范围的开发人员来说,这比使用词法范围本身更成问题。)