Lua变量作用域、函数前向声明和使用'require'语句重构Lua脚本

我发现 Lua 的作用域规则有点困惑。我在下面提交了一个 Lua 脚本片段来突出我想要询问问题的问题:

-- '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' 中,并通过替换函数定义为 require 'warfuncs.lua' 将其导入到脚本中?

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

如果 Lua 嵌入到 C 或 C++ 中(其中可能正在创建堆上的对象),那么作用域规则是否会改变?

原文链接 https://stackoverflow.com/questions/4957473

点赞
stackoverflow用户107090
stackoverflow用户107090

war_is_needed 不能在 while 循环之后移动。如果 while 循环包含在函数中,则可以在其之后移动 war_is_needed。由于所有东西都是全局的,因此对于第二个问题的答案是是。

2011-02-10 13:24:08
stackoverflow用户135758
stackoverflow用户135758

lhf 是正确的,你可以重构你的代码并且它仍然能够工作。不过需要注意的是,尽管这个特定的脚本中的所有内容都是全局的,但是如果处理的变量实际上是临时的(比如在循环或单个函数的作用域内),最好将它们声明为 local

关于第三个问题——在 C/C++ 中嵌入 Lua 脚本,Lua 脚本中的作用域规则与之前没有差别,因为应用程序会创建一个 Lua 状态,并且加载你的脚本文件。任何执行 require 的文件都是在 C/C++ 应用程序初始化期间加载到状态作用域中执行的。

2011-02-10 13:40:28
stackoverflow用户513763
stackoverflow用户513763

据我所知,您只需确保在使用函数/变量/等前先定义它们,所以这个代码片段不会出现问题。

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

但这个就会出现问题:

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

因此,在运行函数和有效地使用变量之前,所有内容都需要被定义。无论您是在主脚本中定义它们,还是在dofile/require中定义它们都无所谓。

2011-02-10 14:23:56