【问题标题】:Lua variable scope, function forward declaration and refactoring a Lua script by using the 'require' statementLua 变量作用域、函数前向声明和使用“require”语句重构 Lua 脚本
【发布时间】:2011-02-10 22:52:25
【问题描述】:

我发现 Lua 的范围规则有点混乱。我在下面提交了一个 Lua 脚本的 sn-p,以突出我想问的问题:

-- 'forward definitions'
-- could these be moved to the bottom of the script to 'tidy up' the script?
-- could these reside in another file imported by require 'filename' to tidy up the script even more?

[[ Note: This function is accessing variables defined later on/elsewhere in the script
         and is also setting a variable (flag) which is then used elsewhere in the script
]]

function war_is_needed()
    if (goodwill:extendsToAllMen() and peace) then
        if player:isAppointedLeader() then
           economy_is_booming = false
           return true
        else
           economy_is_booming = nil
           return true
        end           
    else
        economy_is_booming = nil
        return false
    end
end



world = WorldFactory:new('rock#3')
player = PlayerFactory:getUser('barney', world)

while (not player:isDead()) do
    peace = world:hasPeace()
    goodwill = world:getGoodwillInfo()

    if war_is_needed() then
       world:goToWar()
    else
       if (not economy_is_booming) then
           player:setNervousState(true)
           player:tryToStartAWar()
       else
           player:setNervousState(false)
           player:liveFrivously()
       end if
    end   
end

我的问题是(暂时忽略全局变量可以被认为是邪恶的):

  • 能否将脚本顶部的函数移至脚本底部以“整理”脚本?
  • 能否将脚本顶部的函数重构(即移动)到单独的文件“warfuncs.lua”中,然后通过将函数定义替换为需要“warfuncs.lua”来导入脚本?

在回答上述两个问题时,请记住,脚本顶部的函数正在访问脚本中稍后/其他地方定义的变量 并且还设置了一个变量(标志),然后在脚本的其他地方使用。

如果 Lua 嵌入在 C 或 C++ 中(可能在堆上创建对象),范围规则是否会改变?

【问题讨论】:

    标签: c++ c lua


    【解决方案1】:

    war_is_needed 在 while 循环之后不能移动。如果 while 循环包含在函数中,则可以将 war_is_needed 移到它后面。由于一切都是全球性的,所以第二个问题的答案是肯定的。

    【讨论】:

      【解决方案2】:

      lhf 是正确的,你可以重构你的代码,它仍然可以工作。但请记住,虽然此特定示例脚本中的所有内容都是全局的,但如果使用有效临时的变量(例如,在循环或单个函数的范围内),将它们声明为通常是一个好主意local

      关于在 C/C++ 中嵌入的第三个问题,Lua 脚本中的范围规则没有区别,因为应用程序会创建一个单一的 Lua 状态并加载您的脚本文件。任何执行 require 的文件都在它们在 C/C++ 应用程序初始化期间加载到的状态范围内执行此操作。

      【讨论】:

        【解决方案3】:

        AFAIK 你只需要确保在使用它们之前定义你的函数/变量/ ...,所以这个 sn-p 不会出现问题

        function foo()
            print(a)
        end
        a="Bar!"
        foo()
        

        但这会:

        a="Bar!"
        foo()
        function foo()
            print(a)
        end
        

        所以一切都需要在函数运行之前定义好,并有效地使用变量。无论您是在主脚本中定义它们还是 dofile/require 它们都无关紧要。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-04-05
          • 2014-06-11
          • 1970-01-01
          • 1970-01-01
          • 2012-03-07
          • 1970-01-01
          • 2021-03-10
          • 2021-04-27
          相关资源
          最近更新 更多