之前一直想把csv转成更高效的lua,所以想用继承的方式去转换。但对于像csv这种会有N多table去继承同一个table或者多个基础table的场景下,就不太适合多层继承。下面先来看一下基本的设置元表。
想要在lua中实现继承,可以设置元表来实现setmetatable()
比如:
1 2 3 4 5 6 7 8 9 10 | local defaultTable = { __index = { Id = 1, Type = 2, } } local entry = {} setmetatable(entry, defaultTable) print(entry.Id) --1 |
Lua 查找一个表元素时的规则,其实就是如下 3 个步骤:
1.在表中查找,如果找到,返回该元素,找不到则继续
2.判断该表是否有元表,如果没有元表,返回 nil,有元表则继续。
3.判断元表有没有 __index 方法,如果 __index 方法为 nil,则返回 nil;如果 __index 方法是一个表,则重复 1、2、3;如果 __index 方法是一个函数,则返回该函数的返回值。
按照这个逻辑,我们可以实现多继承。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | local default0 = { VisibleAvatar="1", } local default1 = { Name= "zhangsan", } local default2 = { type=1, } -- 设置default1 继承自 default0 setmetatable(default1, {__index = default0}) -- 设置default2 继承自 default1 setmetatable(default2, {__index = default1}) local ret = {} local entry = nil entry = {Id=1} -- 设置entry 继承自 default2 setmetatable(entry, {__index = default2}) ret[1] = entry print("self : " .. ret[1].Id) print("default2 : " .. ret[1].type) print("default1 : " .. ret[1].Name) print("default0 : " .. ret[1].VisibleAvatar) |

继承的好处就不多讲了,缺点也比较明显,就是内存占用也会随着继承的数量增加而增加,毕竟每一个继承都是一个table。所以在使用的时候一定要注意。