转载自:http://www.cnblogs.com/JimLy-BUG/p/5364281.html
__index元方法:用于查看表中元素是否存在,如果不存在返回结果为nil;如果存在,则由__index返回结果
存在__index元方法:
myTable = setmetatable({key1 = "lua", key3 = "java"}, { __index = function(myTable, key) if key == "key2" then return "key2 is nil" else return myTable[key] end end })
程序运行输出:
---------- 新建程序 ---------- lua key2 is nil java 输出完成 (耗时 0 秒) - 正常终止
不存在__index元方法:
myTable = {key1 = "lua", key3 = "java"} print(myTable.key1, myTable.key2, myTable.key3)
程序运行输出:
---------- 新建程序 ---------- lua nil java 输出完成 (耗时 0 秒) - 正常终止
__newindex元方法:用来对表进行更新。给一个表的缺少的索引赋值时,解释器就会查找是否存在__newindex元方法,
如果存在则调用这个函数而不进行赋值操作;不存在则进行赋值操作。(只针对表中不存在的索引有效)
存在__newindex元方法:
myTable = {key1 = "lua", key3 = "java"} setmetatable(myTable, { __newindex = function(myTable, key, value) print(key .. " is not exists in myTable " .. value) end }) myTable.key1 = "hello" myTable.key2 = "world" --给key2赋值会执行__newindex函数 print(myTable.key1, myTable.key2)
程序运行输出:
---------- 新建程序 ---------- key2 is not exists in myTable world hello nil 输出完成 (耗时 0 秒) - 正常终止
解释说明: 在给myTable表的key1索引赋值时,因为key1索引是myTable中已经存在的索引,
所以只进行赋值而不调用__newindex元方法;
在给myTable表的key2索引赋值时,因为key2索引在myTable表中不存在,解释器就会查找
是否存在__newindex元方法,又由于存在__newindex元方法,所以调用了__newindex元方法
而不对key2索引进行赋值;若不存在__newindex方法,则对新索引进行赋值操作。
不存在__newindex元方法:
myTable = {key1 = "lua", key3 = "java"} myTable.key1 = "hello" myTable.key2 = "world" print(myTable.key1, myTable.key2)
程序运行输出:
---------- 新建程序 ---------- hello world 输出完成 (耗时 0 秒) - 正常终止
__add元方法:用于操作表与表之间的关联事件。当两张表之间用到字符'+'时,解释器就会去查找是否存在__add元方法,
若存在__add元方法,则调用__add元方法,否则程序执行报错。(对应的运算符:'+')
存在__add元方法:
myTable = {10, 20, 30} newTable = {20, 30, 40} setmetatable(myTable, { __add = function(myTable, newTable) print("add") --此处用来处理相关事件,可遍历两个对其中的元素进行累加求和并返回 return "already add" end }) print(myTable + newTable)
程序运行输出:
---------- 新建程序 ---------- add already add 输出完成 (耗时 0 秒) - 正常终止
__sub元方法:用法类似于__add元方法。(对应的运算符:'-')
myTable = {10, 20, 30} newTable = {20, 30, 40} setmetatable(myTable, { __sub = function(myTable, newTable) --__sub可替换__mul/__div/__mod/__unm/__concat/__eq/__lt/__le print("subtract") --处理相关事件 return "already subtract" end }) print(myTable - newTable) --此处要替换为相应的对应运算符
程序运行输出:
---------- 新建程序 ---------- subtract already subtract 输出完成 (耗时 0 秒) - 正常终止
类似于__add和__sub元方法的还有:
__mul元方法:对应运算符'*'
__div元方法:对应运算符'/'
__mod元方法:对应运算符'%'
__pow元方法:对应运算符'^'
__unm元方法:对应运算符'-',此处的运算符不是减号,是代表负数
__concat元方法:对应运算符'..'
__eq元方法:对应运算符'=='
__lt元方法:对应运算符'<'
__le元方法:对应运算符'<='
最后再拿__unm元方法举例:
myTable = {10, 20, 30} setmetatable(myTable, { __unm = function(myTable) print("nagative") --处理相关事件 return "already nagative" end }) print(-myTable)
程序运行输出:
---------- 新建程序 ---------- nagative already nagative 输出完成 (耗时 0 秒) - 正常终止
__call元方法:用于表变量调用一个参数时调用__call元方法。
myTable = {10, 20, 30} num = 100 setmetatable(myTable, { __call = function(myTable, param) --此处的param可替换其他类型的变量 print("call " .. param) --处理相关事件 return "already call" end }) print(myTable(num)) --myTable调用num变量
程序运行输出:
---------- 新建程序 ---------- call 100 already call 输出完成 (耗时 0 秒) - 正常终止
__tostring元方法:用于修改表的输出行为。【类似于JAVA中类中重写了toString()方法,用于修改对象的输出行为】
--写法一 myTable = {10, 20, 30} setmetatable(myTable, { __tostring = function(myTable) --注意__tostring是两个_开头 local sum = 0 for _,v in pairs(myTable) do --注意此处的_字符也表示变量,可用字母k或其他字母替代 sum = sum + v end return ("表元素之和=" .. sum) end }) print(myTable)
--写法二 myTable = {10, 20, 30} mt = {} mt.__tostring = function(myTable) local sum = 0 for _,v in pairs(myTable) do sum = sum + v end return ("表元素之和=" .. sum) end setmetatable(myTable, mt) print(myTable)
循环遍历部分也可修改为:
for index = 1,#myTable do sum = sum + myTable[index] end
程序运行输出:
---------- 新建程序 ---------- 表元素之和=60 输出完成 (耗时 0 秒) - 正常终止