2017-08-09 25 views
1

这个特殊的示例函数在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

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

+0

我不知道函数也可能是本地的。谢谢!对于未来的读者,可以在这里找到解释:https://www.lua.org/pil/6.2.html –