0基础lua学习(十三)Metatable
2017-11-04 14:26
561 查看
简介
在 Lua table 中我们可以访问对应的key来得到value值,但是却无法对两个 table 进行操作。因此 Lua 提供了元表(Metatable),允许我们改变table的行为,每个行为关联了对应的元方法。
setmetatable(table,metatable): 对指定table设置元表(metatable),如果元表(metatable)中存在__metatable键值,setmetatable会失败 。
getmetatable(table): 返回对象的元表(metatable)。
setmetatable和getmetatable
mytable = {} -- 普通表 mymetatable = {} -- 元表 setmetatable(mytable,mymetatable) -- 把 mymetatable 设为 mytable 的元表 --以上代码也可以直接写成一行: mytable = setmetatable({},{}) --以下为返回对象元表: getmetatable(mytable) -- 这回返回mymetatable
__index
__index 元方法这是 metatable 最常用的键。Lua查找一个表元素时的规则,其实就是如下3个步骤:
1.在表中查找,如果找到,返回该元素,找不到则继续
2.判断该表是否有元表,如果没有元表,返回nil,有元表则继续。
3.判断元表有没有__index方法,如果__index方法为nil,则返回nil;如果__index方法是一个表,则重复1、2、3 如果__index方法是一个函数,则返回该函数的返回值(table和键会作为参数传递给函数)。
mytable = setmetatable({key1 = "value1"}, { __index = function(mytable, key) if key == "key2" then return "metatablevalue" else return nil end end }) print(mytable.key1,mytable.key2) --简化版 mytable = setmetatable({key1 = "value1"}, { __index = { key2 = "metatablevalue" } }) print(mytable.key1,mytable.key2)
console:
value1 metatablevalue
value1 metatablevalue
__newindex
用来对表更新,__index则用来对表访问 。当你给表的一个缺少的索引赋值,解释器就会查找__newindex 元方法:如果存在则调用这个函数而不进行赋值操作。
mymetatable = {} mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable }) print(mytable.key1) --调用newkey的时候,发现mytable表中没有newkey ,所以会调用元方法,而不进行赋值 --如果对已存在的索引键(newkey),则会进行赋值,而不调用元方法 __newindex mytable.newkey = "新值2" print(mytable.newkey,mymetatable.newkey) mytable.key1 = "新值1" print(mytable.key1,mymetatable.key1) print("-----------------------------------") mytable = setmetatable({key1 = "value1"}, { __newindex = function(mytable, key, value) rawset(mytable, key, "\""..value.."\"") end }) mytable.key1 = "new value" mytable.key2 = 4 print(mytable.key1,mytable.key2)
console:
value1
nil 新值2
新值1 nil
__add
表的相加操作符-- 计算表中最大值,table.maxn在Lua5.2以上版本中已无法使用 -- 自定义计算表中最大键值函数 table_maxn,即计算表的元素个数 function table_maxn(t) local mn = 0 for k, v in pairs(t) do if mn < k then mn = k end end return mn end -- 两表相加操作 mytable = setmetatable({ 1, 2, 3 }, { __add = function(mytable, newtable) for i = 1, table_maxn(newtable) do table.insert(mytable, table_maxn(mytable)+1,newtable[i]) end return mytable end }) secondtable = {4,5,6} mytable = mytable + secondtable for k,v in ipairs(mytable) do print(k,v) end
console:
1 1
2 2
3 3
4 4
5 5
6 6
有点类似C++的 重载运算符
注意:_ _是两个下划线,连在一起!
模式 | 描述 |
---|---|
__add | 对应的运算符 ‘+’. |
__sub | 对应的运算符 ‘-‘. |
__mul | 对应的运算符 ‘*’. |
__div | 对应的运算符 ‘/’. |
__mod | 对应的运算符 ‘%’. |
__unm | 对应的运算符 ‘-‘. |
__concat | 对应的运算符 ‘..’. |
__eq | 对应的运算符 ‘==’. |
__lt | 对应的运算符 ‘<’. |
__le | 对应的运算符 ‘<=’. |
__call
__call 元方法在 Lua 调用一个值时调用。-- 计算表中最大值,table.maxn在Lua5.2以上版本中已无法使用 -- 自定义计算表中最大键值函数 table_maxn,即计算表的元素个数 function table_maxn(t) local mn = 0 for k, v in pairs(t) do if mn < k then mn = k end end return mn end -- 定义元方法__call mytable = setmetatable({10}, { __call = function(mytable, newtable) sum = 0 for i = 1, table_maxn(mytable) do sum = sum + mytable[i] end for i = 1, table_maxn(newtable) do sum = sum + newtable[i] end return sum end }) newtable = {10,20,30} print(mytable(newtable))
console:
70
__tostring
__tostring 元方法用于修改表的输出行为mytable = setmetatable({ 10, 20, 30 }, { __tostring = function(mytable) sum = 0 for k, v in pairs(mytable) do sum = sum + v end return "表所有元素的和为 " .. sum end }) print(mytable)
console:
表所有元素的和为 60
相关文章推荐
- 0基础lua学习(十五)metatable和__index 实现的继承
- Lua基础教程之表(Table)学习笔记
- cocos-lua基础学习(八)Layer类学习笔记
- 0基础lua学习(二十)Lua单例
- 0基础lua学习(五)赋值语句
- 0基础lua学习(十八)C调用Lua----02Lua堆栈
- Lua学习之metatable and metamethods(一)
- php【基础学习十三】零散知识点
- Lua基础学习(一)
- cocos-lua基础学习(10)scheduler类学习笔记
- lua语言-《lua程序设计》1~5章基础学习
- C#语言学习--基础部分(十三)枚举类型和结构体
- 0基础lua学习(十四)封装
- lua 基础学习第一篇
- lua学习之入门(二)----基础语法1
- lua基础学习 - 非全局函数
- c语言学习之基础知识点介绍(十三):枚举的介绍和使用
- lua学习笔记(1) --Lua基础语法
- JAVA基础学习(十三)--String、StringBuilder、StringBuffer与包装类
- 笔记: Lua基础: Metatable, 多重返回值, 迭代器