我是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()
在这个例子中,“class”lkw可以使用new创建对象,但self
和index
是什么意思?
应该在java / C ++中将self
视为this
,索引是什么?
答案 0 :(得分:2)
这种风格的OOP在Lua中很常见。我不喜欢它,因为它对我来说不够明确,但让我试着解释一下。
有两个令人困惑的事情:在函数定义中使用:
糖,并使用“class”作为其实例的元表。
首先,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)
现在,这是“原型继承”。 lkw
是mylkw
等实例的“原型”。这与“阶级”类似,但略有不同。
调用new
构造函数时,lkw
将作为self
参数传递。
构造函数的第二行和第三行很奇怪。这可能更容易理解:
lkw.new = function(self)
local res = {}
setmetatable(res, {__index = lkw})
return res
end
即:如果我们在实例中没有找到某些内容,我们会在原型中查找它。
这解释了func
的工作原理。第一次调用它时,实例将不包含la
键,因此将使用lkw.la
。
代码不以这种方式编写的原因是奇怪的构造允许“原型继承”:你可以在mylkw
上调用“new”并得到一个“实例的实例” “(即在原型继承中,实例和子类是相同的东西)。
我认为这是一个非常令人困惑的功能。作为参考,这是关于我如何编写有关同一事物的代码,没有继承:
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()