在 Lua 中使用“对象”函数?

8bi*_*ime 3 lua metatable lua-table

我希望能够在 Lua 中拥有具有某些函数的“对象”,这些函数引用它们自己(我不知道该怎么称呼它)。我已经看过我想要做的事情的代码,但我从来没有理解它的实际含义。我尝试过浏览 Lua 网站,但没有成功。

基本代码:

table = {}

function newTable(...)
  ...
  return setmetatable(table)
end

function table:funcName(...)
  ...
end
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下这里发生了什么以及我如何使用它吗?谢谢阅读!

gre*_*olf 5

Missingno 已经提到了一项解释其工作原理的资源。您还可以查看lua wiki 的 OOP部分以获取更多解释和示例。

简要总结您的示例,从如何使用它开始。注意,我更改了一些名称,因此它不会影响 lua 附带的标准模块。您可以通过调用创建一个新对象newObject:您可以使用后跟方法名称来调用该对象的方法:

-- create two instances
object1 = newObject()
object2 = newObject()

-- call 'my_function' method for object1
object1:my_function()
Run Code Online (Sandbox Code Playgroud)

您需要了解一些有关元表的知识才能了解该机制在幕后的工作原理。当您执行如下调用时:

object1:my_function()
Run Code Online (Sandbox Code Playgroud)

这只是语法糖:

object1.my_function(object1)
Run Code Online (Sandbox Code Playgroud)

这可以进一步细分为:

object1["my_function"](object1)
Run Code Online (Sandbox Code Playgroud)

现在object1只是newObject-- 返回的一个空表,它没有键"my_function"。通常这会导致错误,因为您正在尝试调用一个nil值。但是,您可以使用元表更改此行为。基本思想是设置__index元方法以指向保存类方法的表:

object_table = {}
object_table.__index = object_table
function newObject(...)
  return setmetatable({}, object_table)
end
Run Code Online (Sandbox Code Playgroud)

方法查找过程将如下所示:object1-> table。如果object1没有钥匙,table则接着咨询。如果table有该键,则返回关联的值。如果table也没有,则nil返回,因为table没有元表。

通过此设置,您只需将方法名称和函数分配为该对象的键值对,即可“覆盖”特定对象实例的方法。

object2.my_function = function (...)
  -- do something different
end
Run Code Online (Sandbox Code Playgroud)