Lua 中的类,它是如何工作的

Eng*_*ine 3 lua

我是 Lua 的新手,我正在尝试理解它的 OO 部分,例如:

lkw = {}
lkw.la= 0

function lkw:func(ge)
    self.la = self.la + ge
end

function lkw:new()
    local res = {}
    setmetatable(res, self)
    self.__index = self
    return res
end

mylkw = lkw:new()
Run Code Online (Sandbox Code Playgroud)

在此示例中,“类”lkw 可以使用 new 创建对象,但是 和 是什么self意思indexself应该像在 java/C++ 中一样考虑this,索引是什么?

cat*_*ell 5

这种 OOP 风格在 Lua 中很常见。我不喜欢它,因为它对我来说不够明确,但让我尝试解释一下。

有两个令人困惑的事情:在函数定义中使用糖:和使用“类”作为其实例的元表。

首先,function a:b(...)与 相同a.b = function(self, ...),所以让我们删除所有糖:

lkw = {}
lkw.la = 0

lkw.func = function(self, ge)
    self.la = self.la + ge
end

lkw.new = function(self)
    local res = {}
    setmetatable(res, self)
    self.__index = self
    return res
end

mylkw = lkw.new(lkw)
Run Code Online (Sandbox Code Playgroud)

现在,这就是“原型继承”。lkw是诸如 之类的实例的“原型” mylkw。这与“类”类似但略有不同。

new调用构造函数时,lkw作为参数传递self

构造函数的第二行和第三行很奇怪。这可能更容易理解:

lkw.new = function(self)
    local res = {}
    setmetatable(res, {__index = lkw})
    return res
end
Run Code Online (Sandbox Code Playgroud)

即:如果我们在实例中找不到某些东西,我们就会在原型中寻找它。

这解释了如何func工作。第一次调用时,实例将不包含密钥,la因此lkw.la将被使用。

代码不以这种方式编写的原因是奇怪的构造允许“原型继承”:您可以调用“new”mylkw并获取“实例的实例”(即在原型继承中,实例和子类是相同的)事物)。

我认为这是一个非常令人困惑的功能。作为参考,这是关于我如何编写执行相同操作但没有继承的代码:

local methods = {
    func = function(self, ge)
        self.la = self.la + ge
    end
}

local lkw = {
    new = function()
        return setmetatable({la = 0}, {__index = methods})
    end
}

local mylkw = lkw.new()
Run Code Online (Sandbox Code Playgroud)