递归迭代器的词法范围如何工作?
问题描述:
这个特殊的示例函数在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,这是内循环结束!
任何人都可以帮助解释为什么这种奇怪的行为发生?
答
我相信你的问题在于第3行 - 你声明iter
作为一个全局函数而不是本地函数,这使得它可以从任何Lua块进行访问。将该行更改为local function iter()
可更正此行为。我认为,这是开发人员应用词汇范围的问题,而不是词法范围本身:)
我不知道函数也可能是本地的。谢谢!对于未来的读者,可以在这里找到解释:https://www.lua.org/pil/6.2.html –