在Lua中,我们像这样进行OO编程:
MyClass = {}
function MyClass:new()
local obj = {}
setmetatable(obj, self)
self.__index = self
obj.hello = "hello world"
return obj
end
function MyClass:sayHi()
print(self.hello)
end
function main()
local obj = MyClass:new()
obj:sayHi()
end
在处理更多compelx内容时,通常我会利用Lua的元方法来代理函数调用,并通过添加以下内容来完成我需要做的事情,例如参数解析等:
MyClassMeta = {}
function MyClassMeta.__index(obj, funcName)
return function (self, ...)
//do some stuff
print("you called " .. funcName .. " with args", ...)
end
end
并更改行:
setmetatable(obj, self)
收件人:
setmetatable(obj, MyClassMeta)
我使用MyClass
实例调用的每个函数都将执行在MyClassMeta.__index
元方法中实现的代码。
我现在想做的是继承MyClass
现有方法,并仅对不属于MyClassMeta.__index
的函数执行MyClass
。
在上面的示例中,即使调用MyClassMeta.__index
,代码也会始终执行MyClass:sayHi()
元方法:
function main()
local obj = MyClass:new()
obj:sayHi("hello")
end
您通过args打了个电话“ hiyHi”
答案 0 :(得分:1)
将__index
设置为表时,它将在该表上查找属性,如果实例中不存在这些属性,则将其返回。由于sayHi
存在于MyClass
表中。
self.__index = self
将__index
设置为一个函数时,它可以为实例上不存在的属性返回任何内容。您可以检查键是否存在于MyClass表上并返回它,如果不存在,请执行其他操作:
MyClass = {}
MyMetatable = {
__index = function(obj, key)
if MyClass[key] ~= nil then return MyClass[key] end
return function(self, ...)
print("you called "..tostring(key))
print(" self.hello is '"..tostring(self.hello).."'")
print(" with args", ...)
end
end
}
function MyClass:new()
local obj = {}
setmetatable(obj, MyMetatable)
obj.hello = "hello world"
return obj
end
function MyClass:sayHi()
print(self.hello)
end
function main()
local obj = MyClass:new()
obj:sayHi()
end
local obj = MyClass:new()
obj:sayHi("hello")
obj:somethingElse(1, 2, 3)
带有Egor评论的版本
MyClass = {}
setmetatable(MyClass, {
-- if it's not found on MyClass, return a function
__index = function(self, funcName)
return function(self, ...)
print("you called "..funcName.." with args", ...)
end
end
})
function MyClass:new()
local obj = {}
-- if it's not found on obj, try self (MyClass)
setmetatable(obj, { __index = self })
obj.hello = "hello world"
return obj
end
function MyClass:sayHi()
print(self.hello)
end
local obj = MyClass:new()
obj:sayHi()
obj:somethingElse(1, 2, 3)
在创建对象时,这会将新对象的元表的__index
设置为MyClass
,并将MyClass的元表的索引设置为后备功能。因此,如果该属性不在MyClass上的对象或上,它将使用后备。