- 今天在用pairs遍历一个类(table)的数据成员时发现一个奇怪的现象,代码如下
A={} function A:new() local o={} setmetatable(o,self) self.__index=self self.a=1 self.b=2 self.c=3 return o end function A:show() print(self.a,self.b,self.c) end local c1=A:new() c1:show() ---输出1 2 3 ---这里没有输出 for k,v in pairs(c1) do print(k,v) end print(c1.a,c1.b,c1.c) ---输出1 2 3
用for循环加Pair遍历时发现没输出。
- 原来还是对元表的理解不够,这里new()函数返回的是table o,所以c1可以看成是o,而o本身没有数据成员,a,b,c都是它的 元表A的成员,自然无法用pairs遍历到。o本来也没有show()函数成员,但是它有设置元表A,且元表的__index就等于元表A本身,所以c1(o)可以访问到show().。同理也可以访问到a,b,c成员。table访问成员的流程如下:
o中有没有show这个键? 有 --> 返回show对应的值
|
没有
|
o中是否设置过metatable? 否 --> 返回nil
|
有
|
在o的metatable中有没有__index这个键? 没有 --> 返回nil
|
有
|
在o的metatable中的__index这个键对应的表中有没有show这个键? 没有 --> 返回nil
|
有,返回getmetatable(p).__index.talk
- 为了能直接用pairs遍历类的所以数据成员,项目中所以类的成员都按如下定义
A={} function A:new() local o={} setmetatable(o,self) self.__index=self o.a=1 o.b=2 o.c=3 return o end function A:show() print(self.a,self.b,self.c) end local c1=A:new() c1:show() ---输出1 2 3 ---这里没有输出 for k,v in pairs(c1) do ---这里能输出但是顺序不是a,b,c.pairs的问题 print(k,v) end print(c1.a,c1.b,c1.c) ---输出1 2 3