永州冷水滩网站建设,没经验可以做电商运营吗,怎样做月嫂网站,google搜索引擎官网元表与元方法的概念
Lua中每个值都可具有元表。元表是普通的Lua表,定义了原始值在某些特定操作下 的行为。
例如,当table作为加法的操作数时,Lua检查其“元表”中的“__add”字段是否有 个函数。如果有,Lua调用它执行加法。我们称“元表”中的“键(如__add)”为事件(event),称…元表与元方法的概念
Lua中每个值都可具有元表。元表是普通的Lua表,定义了原始值在某些特定操作下 的行为。
例如,当table作为加法的操作数时,Lua检查其“元表”中的“__add”字段是否有 个函数。如果有,Lua调用它执行加法。我们称“元表”中的“键(如__add)”为事件(event),称“值”为元方法(metamethod)。前述例子中的事件(event)是__add,元方法(metamethod)是执行加法的函数。
又例如使用元表我们可以定义Lua如何计算两个table的相加操作ab。当Lua试图对两个表进行相加时先检查两者之一是否有元表之后检查是否有一个叫__add的字段若找到则调用对应的值。__add 等即时字段其对应的值往往是一个函数或是table就是元方法。
自己的理解:可以理解为“元方法(metamethod)”只存在与“元表”中。或者认为在元表中元方法才有意义。
Lua创建新的table的同时不会创建元表但是可以使用“setmetatable”函数为table设置原表
当你通过键来访问table的时候如果这个键没有值那么Lua就会寻找该table的元表(metatable)(假定有metatable)中的__index键。如果__index 包含一个表格Lua会在表格中查找对应的键。如果__index包含一个函数的话Lua就会调用那个函数table和键会作为参数传递给函数。__index元方法查看表中元素是否存在如果不存在返回结构为nil;如果存在则由__index返回结果。
元方法
常用元方法
__add:加法 __sub:减法__mul:乘法__div:除法__unm:相反数__mod:取模__pow:乘幂__index:__newindex:等
关系类的元方法
除了加法减法这些算术类的操作之外,大于小于等这些关系类的操作也是有元方法的:
__eq:等于__lt:小于__le:小于等于
如果对两个具备不同“元表”的值进行这些比较操作,就会报错,一定要注意,这和加减法的规则不一样。
测试用例 local mtab1 {}
mtab1.Name mtab1 name
-- 元方法:加法
mtab1.__add function(t1, t2)local val mtab1.__add-- print(val)return val
end
-- 元方法:减法
mtab1.__sub function(t1, t2)local val mtab1.__sub-- print(val)return val
end
-- 元方法:小于
mtab1.__lt function(t1, t2)local val mtab1.__ltprint(call metamethod:, val)math.randomseed(os.time())local rval math.random(1, 10)-- for i 1, 10 do-- rval math.random(1, 10)-- endreturn rval 5
endlocal mtab2 {}
mtab2.Name mtab2 name
-- 元方法:加法
mtab2.__add function(t1, t2)local val mtab2.__add-- print(val)return val
end
-- 元方法:减法
mtab2.__sub function(t1, t2)local val mtab2.__sub-- print(val)return val
endlocal tab1 {}
local tab2 {}
local tab3 {}
local tab4 {}
-- 元方法:加法,如果没有将 tab4 这是为其它 table 的元表,好像没有意义
tab4.__add function(t1, t2)local val tab4.__add-- print(val)return val
end--此 table 没有元表
local tab5_nomet {}
-- 元方法:加法
tab5_nomet.__add function(t1, t2)local val tab5_nomet.__add-- print(val)return val
endlocal tab6 {}
local tab7 {}--此 table 没有元表
local tab8_nomet {}-- 为 table 表设置 元表
setmetatable(tab1, mtab1)
setmetatable(tab2, mtab1)
setmetatable(tab3, mtab2)
setmetatable(tab4, {__index mtab1})
setmetatable(tab6, tab5_nomet)
setmetatable(tab7, tab4)-------------------------------------------------------- 输出table表的地址
print(tab1, tab2, tab3, tab4, mtab1, mtab2)
-- 输出tabled表的原表地址
-- getmetatable(tab1)与 getmetatable(tab2)的值相等是因为 tab1 与 tab2 的 元表 都是 mtab1
print(getmetatable(tab1),getmetatable(tab2),getmetatable(tab3),getmetatable(tab4),getmetatable(mtab1),getmetatable(mtab2)
)-- 输出表 keyName 的值
print(tab1.Name,tab1.Name,,tab2.Name,tab2.Name,,tab3.Name,tab3.Name,,tab4.Name,tab4.Name,,mtab1.Name,mtab1.Name,,mtab2.Name,mtab2.Name
)
------------------------------------------------------------------------------------------------------------
-- 不同元表:第一个值有元表操作符前面,就以这个元表为准看是否有元方法,如果没有就看第二个元表是否有元方法。都没有元方法就会报错。
-- 都没有元表。所以,报错:attempt to perform arithmetic on local mtab1 (a table value)
-- print(mtab1 mtab2 ,mtab1 mtab2)
------------------------------------------------------
-- 相同元表:执行元表中的元方法
-- 输出:tab1 tab2 mtab1.__add
print(tab1 tab2 , tab1 tab2)
-- 不同元表:第一个值有元表操作符前面,就以这个元表为准看是否有元方法,如果没有就看第二个元表是否有元方法。都没有元方法就会报错。
-- 输出:tab1 tab3 mtab1.__add
print(tab1 tab3 , tab1 tab3)
-- 不同元表:第一个值有元表操作符前面,就以这个元表为准看是否有元方法,如果没有就看第二个元表是否有元方法。都没有元方法就会报错。
-- 输出:tab1 tab4 mtab1.__add
print(tab1 tab4 , tab1 tab4)
-- 不同元表:第一个值有元表操作符前面,就以这个元表为准看是否有元方法,如果没有就看第二个元表是否有元方法。都没有元方法就会报错。
-- 输出:tab1 tab5_nomet mtab1.__add
print(tab1 tab5_nomet , tab1 tab5_nomet)
-- 不同元表:第一个值有元表操作符前面,就以这个元表为准看是否有元方法,如果没有就看第二个元表是否有元方法。都没有元方法就会报错。
-- 输出:tab5_nomet tab1 mtab1.__add
print(tab5_nomet tab1 , tab5_nomet tab1)
-- 不同元表:第一个值有元表操作符前面,就以这个元表为准看是否有元方法,如果没有就看第二个元表是否有元方法。都没有元方法就会报错。
-- 输出:tab4 tab1 mtab1.__add
print(tab4 tab1 , tab4 tab1)
------------------------------------------------------
-- 不同元表:第一个值有元表操作符前面,就以这个元表为准看是否有元方法,如果没有就看第二个元表是否有元方法。都没有元方法就会报错。
-- tab4有原表,但是没有__add元方法,tab5_nomet也没有__add元方法。所以,报错:attempt to perform arithmetic on local tab4 (a table value)
-- print(tab4 tab5_nomet ,tab4 tab5_nomet)-- 不同元表:第一个值有元表操作符前面,就以这个元表为准看是否有元方法,如果没有就看第二个元表是否有元方法。都没有元方法就会报错。
-- tab4有原表,但是没有__add元方法,tab5_nomet也没有__add元方法。所以,报错:attempt to perform arithmetic on local tab5_nomet (a table value)
-- print(tab5_nomet tab4 , tab5_nomet tab4)
------------------------------------------------------
-- 输出:tab5_nomet tab6 tab5_nomet.__add
print(tab5_nomet tab6 , tab5_nomet tab6)
-- 输出:tab7 tab8_nomet tab4.__add
print(tab7 tab8_nomet , tab7 tab8_nomet)
-- 输出:tab7 tab4 tab4.__add
print(tab7 tab4 , tab7 tab8_nomet)
-------------------------------------------------------- 输出:tab1 tab2 boolean结果
print(tab1 tab2 , tab1 tab2)
-- 如果对两个具备不同“元表”的值进行这些比较操作,就会报错,一定要注意,这和加减法的规则不一样。
-- 所以,报错:attempt to compare two table values
-- print(tab1 tab3 , tab1 tab3)
print(----------------)
测试用例输出结果
----------------
table: 00C5C9A8 table: 00C5C8E0 table: 00C5C958 table: 00C5C9F8 table: 00C5C9D0 table: 00C5C7F0
table: 00C5C9D0 table: 00C5C9D0 table: 00C5C7F0 table: 00C5C8B8 nil nil
tab1.Name nil ,tab2.Name nil ,tab3.Name nil ,tab4.Name mtab1 name ,mtab1.Name mtab1 name ,mtab2.Name mtab2 name
tab1 tab2 mtab1.__add
tab1 tab3 mtab1.__add
tab1 tab4 mtab1.__add
tab1 tab5_nomet mtab1.__add
tab5_nomet tab1 mtab1.__add
tab4 tab1 mtab1.__add
tab5_nomet tab6 tab5_nomet.__add
tab7 tab8_nomet tab4.__add
tab7 tab4 tab4.__add
call metamethod: mtab1.__lt
tab1 tab2 true
----------------