【问题标题】:How does lexical scoping with recursive iterators work?递归迭代器的词法作用域如何工作?
【发布时间】:2018-01-17 00:15:02
【问题描述】:

这个特殊的示例函数在 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,即内循环结束的地方!

谁能帮助解释为什么会出现这种奇怪的行为?

【问题讨论】:

    标签: recursion iterator lexical-scope


    【解决方案1】:

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

    【讨论】:

    • 我不知道函数也可以是本地的。谢谢!对于未来的读者,可以在这里找到解释:lua.org/pil/6.2.html
    猜你喜欢
    • 2011-02-01
    • 2016-07-21
    • 2014-01-20
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-25
    相关资源
    最近更新 更多