无法弄清楚 lua table 继承
Unable to figure out lua table inheritence
希望有人能理解我试图弄清楚的东西,只是似乎对 Lua 的理解还不足以实现这一目标。
--[[
tbl.a.test("moo") returns "Table A moo appears"
tbl.b.test("moo") returns "moo appears"
]]
tbl = {
a = { ID = "Table A" },
b = {
test = function(...) print(... .. " appears") end,
},
}
tbl.a__index = function(self, ...) tbl.b[self](tbl.a.ID .. ...) end
我正在尝试做的是我可以创建多个表 a、c、d、e 而不必将测试复制到每个表。当使用 tbl.a.test
、tbl.c.test
、tbl.d.test
时,它将检索 tbl.a.ID
var,然后调用 tbl.b.test(ID, "moo")
到目前为止,我所发现的是它无法在 tbl.b
以外的任何其他地方找到 .test
** 编辑 **
感谢大家的支持,目前代码已出;
tbl = {
a = { ID = "Table A " },
b = { test = function(...) local id, rest = ... print(id .. ": " .. rest) end },
}
setmetatable(tbl.a, {__index=function(self, k, ...) local rest = ... return tbl.b[k](tbl.a.ID, rest) end})
但是,由于某些奇怪的原因...没有取得进展:|
- 您错过了
tbl.a
和 __index
之间的句点。
__index
需要在 a
的 metatable 上,而不是 table 本身。
- 您 return 您的
__index
函数中没有任何内容
self
在 __index
函数中索引的是 table,而不是键(即第二个参数)
这应该有效:
setmetatable(tbl.a, {__index=function(self, k) return tbl.b[k](tbl.a.ID) end})
--------------------------------------------------------------------------------
-- [Sub]Class creation
--------------------------------------------------------------------------------
function newclass(new_obj,old_obj)
old_obj = old_obj or {} --use passed-in object (if any)
new_obj = new_obj or {}
assert(type(new_obj) == 'table','New Object/Class is not a table')
assert(type(old_obj) == 'table','Old Object/Class is not a table')
old_obj.__index = old_obj --store __index in parent object (optimization)
return setmetatable(new_obj,old_obj) --create 'new_obj' inheriting 'old_obj'
end
--------------------------------------------------------------------------------
prototype = {
test = function(self,s) print('Table ' .. self.id .. ' ' .. s .. ' appears') end
}
tbl = {}
tbl.a = newclass({id = 'A'},prototype)
tbl.b = newclass({id = 'B'},prototype)
tbl.a:test('moo')
tbl.b:test('moo')
class 和 Lua 中的对象之间的区别只是理论上的。实际上,它们的实现方式完全相同。
任何时候你需要做继承,你可以使用我的通用 newclass() 函数来创建一个新的 class/object,或者从现有的继承。
您希望传递的任何通用代码和数据都应放入 'prototype' table(无论您对每种情况如何称呼)。
此外,您似乎忘记在调用方法时使用方法调用语法(使用冒号而不是点)。没有它,self参数不会被自动识别。
希望有人能理解我试图弄清楚的东西,只是似乎对 Lua 的理解还不足以实现这一目标。
--[[
tbl.a.test("moo") returns "Table A moo appears"
tbl.b.test("moo") returns "moo appears"
]]
tbl = {
a = { ID = "Table A" },
b = {
test = function(...) print(... .. " appears") end,
},
}
tbl.a__index = function(self, ...) tbl.b[self](tbl.a.ID .. ...) end
我正在尝试做的是我可以创建多个表 a、c、d、e 而不必将测试复制到每个表。当使用 tbl.a.test
、tbl.c.test
、tbl.d.test
时,它将检索 tbl.a.ID
var,然后调用 tbl.b.test(ID, "moo")
到目前为止,我所发现的是它无法在 tbl.b
以外的任何其他地方找到 .test** 编辑 ** 感谢大家的支持,目前代码已出;
tbl = {
a = { ID = "Table A " },
b = { test = function(...) local id, rest = ... print(id .. ": " .. rest) end },
}
setmetatable(tbl.a, {__index=function(self, k, ...) local rest = ... return tbl.b[k](tbl.a.ID, rest) end})
但是,由于某些奇怪的原因...没有取得进展:|
- 您错过了
tbl.a
和__index
之间的句点。 __index
需要在a
的 metatable 上,而不是 table 本身。- 您 return 您的
__index
函数中没有任何内容 self
在__index
函数中索引的是 table,而不是键(即第二个参数)
这应该有效:
setmetatable(tbl.a, {__index=function(self, k) return tbl.b[k](tbl.a.ID) end})
--------------------------------------------------------------------------------
-- [Sub]Class creation
--------------------------------------------------------------------------------
function newclass(new_obj,old_obj)
old_obj = old_obj or {} --use passed-in object (if any)
new_obj = new_obj or {}
assert(type(new_obj) == 'table','New Object/Class is not a table')
assert(type(old_obj) == 'table','Old Object/Class is not a table')
old_obj.__index = old_obj --store __index in parent object (optimization)
return setmetatable(new_obj,old_obj) --create 'new_obj' inheriting 'old_obj'
end
--------------------------------------------------------------------------------
prototype = {
test = function(self,s) print('Table ' .. self.id .. ' ' .. s .. ' appears') end
}
tbl = {}
tbl.a = newclass({id = 'A'},prototype)
tbl.b = newclass({id = 'B'},prototype)
tbl.a:test('moo')
tbl.b:test('moo')
class 和 Lua 中的对象之间的区别只是理论上的。实际上,它们的实现方式完全相同。
任何时候你需要做继承,你可以使用我的通用 newclass() 函数来创建一个新的 class/object,或者从现有的继承。
您希望传递的任何通用代码和数据都应放入 'prototype' table(无论您对每种情况如何称呼)。
此外,您似乎忘记在调用方法时使用方法调用语法(使用冒号而不是点)。没有它,self参数不会被自动识别。