Lua中包含文件中重载类函数

很抱歉,我对LUA脚本很陌生,不得不处理他人编写的代码。 请不要关注代码,我的问题只涉及包含文件和优先处理需要调用的函数,在重载的情况下。

假设我有一个包含类Terrain的文件Terrain.lua,其中有一个函数Terrain:generate(),而Terrain:generate()会调用Terrain:getLatitude()。

MyScript.lua覆盖了Terrain:getLatitude()如下所示:

include("Terrain");

    function Terrain:getLatitude()
       新代码;
    end

    function myFunction()
        local myTerrain = Terrain.create();
        myTerrain.generate();
    end

这将覆盖getLatitude():当调用myTerrain.generate()时,generate()是包含在“Terrain”中的代码,但是getLatitude()是带有新代码的本地函数,即使是被包含类的函数调用。

现在假设我想将一些代码放在外部文件Custom.lua中。Custom(而不是MyScript)必须覆盖getLatitude()。 这是情况:

Terrain.lua包含Terrain类和这些函数

Terrain.create()
Terrain.generate()
Terrain.getLatitude()

MyScript.lua是正在执行的脚本,并包括Custom:

include("Custom");

        function myFunction()
            return customFunction()
        end

Custom.lua包括:

include("Terrain");

    function Terrain:getLatitude()
       新代码;
    end

    function customFunction()
        local myTerrain = Terrain.create();
        myTerrain.generate();
    end

现在,如果我从MyScript调用customFunction(),则使用从Terrain中获得的getLatitude(),而不是从Custom中获得的getLatitude()。我假设只能在当前正在执行的文件中进行覆盖?我怎样才能在包含的文件中实现覆盖?

希望这个例子足以理解我的问题,而不必发布大量代码。谢谢。

点赞
用户4687565
用户4687565

首先,有几处需要纠正:您的问题中没有 local functioninclude 不是 Lua 标准库的一部分,该函数实际上的功能可能非常重要。

最后,Lua 没有实际的类系统,您在问题中使用的只是一种语法糖(我认为具有误导性和混淆性),它是关于表赋值的。Lua 是解释型语言,因此对您而言,类定义可能看起来不是从程序执行的开始就已知的静态结构,而是从文件顶部到底部依次执行的代码。

因此,如果我们假设 include 类似于 require,那么您的问题代码将等效于以下内容:

do--terrain.lua
Terrain = {
   create=function()
       local created_object
       --一些代码为 created_object 赋值
       return created_object
   end
}

Terrain.generate = function(self) end

Terrain.getLatitude = function(this_is_a_self_too)
   --一些代码,当作为 object:generate() 调用时,使用 also_self 作为对象的引用
end

--do end 块本质上等价于文件,它的局部变量在外部看不到
--它赋值的全局变量(如 `terrain` )将在结束后保持可访问状态
--对全局变量所做的更改也将保留
end

do--Custom.lua
   Terrain.getLatitude = function(this)--这是对存储在全局变量 Terrain 中的表字段进行的赋值
      --这个函数将替换分配给 `getLatitude` 字段的原来的函数
   end

   customFunction = function()
       local myTerrain = Terrain.create();
       myTerrain.generate();--这个可能需要使用 `:` 而不是 `.`
       --这取决于 terrain.lua 中实际的代码
   end
end

do--MyScript.lua
   myFunction= function()
       return customFunction() --此行调用全局变量 customFunction
   end
end

因此,如果您的实际设置与问题中的设置类似,则“覆盖”将在 Custom.lua 执行后生效,并且对于所有随后调用 Terrain.getLatitude 的调用,无论是否调用了该文件,都将生效。(之后任何文件都可以再次覆盖它,之后的所有调用都将使用新的函数)

在这种设置中进行有限的覆盖可能会更加复杂。这又取决于您的团队如何定义 Terrain 类和类系统的实际细节。

2018-05-16 11:44:36