lua学习笔记16:table元表详解

一 table本质Lua中table本质实际上是个类似HashMap东西。其元素是很多的Key-Value对,类似iOS中的字典NSDictionary。如果尝试访问了一个表中并不存在的元素时,就会触发Lua的一套查找机制。lua“面向对象”就是凭借这个机制实现的。示例:local tab = {}print(tab.key)输出:nil因为tab中没有任何元素,当然视图访问其key元素时就会找不到,所以返回nil。二 元表metatable元表,即元素列表,是table的一个备查找的元素列表;当在table中找不到要访问的元素时,就会到它的元表中中区查找。table的元表我们可以通过函数setmetatable来设置。示例:BaseClass = {base = 1,}DerivedClass = {derived = 2,}setmetatable(DerivedClass, BaseClass)print(DerivedClass.base)输出:nil

已经设置了元表,还是找不到,这是为什么呢?往下看!

三 元方法__index上面可以看到即使设置了元表,还是找不到元表中的元素,这是为什么呢?因为当要在元表中查询元素的时间,并不是在元表中查找元表,而是在元表的__index中查找。

示例

BaseClass = {base = 1,}BaseClass.__index = BaseClassDerivedClass = {derived = 2,}setmetatable(DerivedClass, BaseClass)print(DerivedClass.base)

输出:1另外,__index还可以是函数。示例:BaseClass = {base = 1}BaseClass.__index = function(tab, key)if key == "fun" thenreturn 1elsereturn 0endendDerivedClass = {derived = 2,}setmetatable(DerivedClass, BaseClass)print(DerivedClass.fun)输出:1上面的代码可以简写为:BaseClass = {base = 1,}DerivedClass = setmetatable({derived = 2}, {__index = BaseClass})print(DerivedClass.base)————————————————————————-BaseClass = {base = 1,}DerivedClass = setmetatable({derived = 2}, {__index = function(tab, key)if key == "fun" thenreturn 1elsereturn 0endend})print(DerivedClass.fun)综上所述,可以发现如下规则:1 __index方法用来确定表在被作为元表时的查找方法。2 查找表元素时的过程如下:a.在表中查找,,如果找到,返回该元素,找不到则继续;b.判断该表是否有元表,如果没有元表,返回nil,有元表则继续;c.判断元表是否有__index方法,如果没有,则返回nil,有则继续查找;d.如果__index方法是一个表,则重复a、b、c;e.如果__index方法是一个函数,则返回该函数的返回值。四 __newindex方法当我们赋值时, 查找过程跟上面的一样。如果都没有查找到,就会在元表metatable的__newindex中增加这个元素,然后赋值。示例BaseClass = {base = 1,}BaseClass.__index = BaseClassNewElement = {}BaseClass.__newindex = NewElementDerivedClass = {derived = 2,}setmetatable(DerivedClass, BaseClass)DerivedClass.new = 1print(BaseClass.new)print(NewElement.new)print(DerivedClass.new)输出:nil1nil因为DerivedClass里没有new,查看__newindex,并把new=1传给了NewElement,并没有给DerivedClass里的new赋值。五 __call方法__call 索引, 它允许你把表当函数调用。示例:BaseClass = {}BaseClass.__call = function (BaseClass, a, b)return a + b;endDerivedClass = {derived = 2,}setmetatable(DerivedClass, BaseClass)print(DerivedClass(1, 2))输出:3六 __tostring方法可以把表转化为string, 非常方便类似print的函数使用。BaseClass = {}BaseClass.__tostring = function (BaseClass)local str = "-"for k, v in pairs(BaseClass) dostr = str..">"..k..":"..v..""endreturn strendDerivedClass = {className = "DerivedClass",derived = 2,}setmetatable(DerivedClass, BaseClass)print(DerivedClass)输出:->derived:2>className:DerivedClass

每个人在他的人生发轫之初,总有一段时光,

lua学习笔记16:table元表详解

相关文章:

你感兴趣的文章:

标签云: