metatable基本定义
从lua的 metatable官方解释 中我们可以得到如下信息:
1. 每个table和每个full user data都可以有自己的metatable,并可通过setmetatable和getmetatable进行访问
2. 其他任何lua类型,每种类型共享一个metatable;比如number类型共享一个metatable;string类型共享一个metatable;这些类型的metatable无法更改,除非用C API
3. metatable的key叫事件(event),value叫元方法(metamethod)
4. 除了__index,__newindex可以是function或table外,其他元方法都必须是function
__call元方法释义
当我们写下a(b,c )时,若a不是函数,那么a.metatable.__call(a, ...)将调用:
meta = {}
meta.__call = function(a, b, c) print(a, b, c) end
a = {}
setmetatable(a, meta)
a(10, 11)
__gc元方法释义
注意__gc元方法只对full user data有效
__tostring元方法释义
当调用tostring(a)时,若a不是string,那么a.metatable.__tostring(a)将调用;事实上print会调用tostring
meta = {}
meta.__tostring = function(a) return "a" end -- 必须返回一个字符串
a = {}
setmetatable(a, meta)
print(a)
禁止目标的metatable被修改
setmetatable/getmetatable函数也会使用metafield,在这种情况下,可以保护metatables。假定你想保护你的集合使其使用者既看不到也不能修改metatables。如果你对metatable设置了__metatable的值,getmetatable将返回这个域的值,而调用setmetatable 将会出错:
meta = { __metatable = "not your business" }
a = {}
setmetatable(a, meta) -- ok & metatable protected
print(getmetatable(a)) -- not your business
setmetatable(a, {}) -- error!!!
输出如下:
not your business
lua: .\a.lua:5: cannot change a protected metatable
从lua的 metatable官方解释 中我们可以得到如下信息:
1. 每个table和每个full user data都可以有自己的metatable,并可通过setmetatable和getmetatable进行访问
2. 其他任何lua类型,每种类型共享一个metatable;比如number类型共享一个metatable;string类型共享一个metatable;这些类型的metatable无法更改,除非用C API
3. metatable的key叫事件(event),value叫元方法(metamethod)
4. 除了__index,__newindex可以是function或table外,其他元方法都必须是function
__call元方法释义
当我们写下a(b,c )时,若a不是函数,那么a.metatable.__call(a, ...)将调用:
meta = {}
meta.__call = function(a, b, c) print(a, b, c) end
a = {}
setmetatable(a, meta)
a(10, 11)
__gc元方法释义
注意__gc元方法只对full user data有效
__tostring元方法释义
当调用tostring(a)时,若a不是string,那么a.metatable.__tostring(a)将调用;事实上print会调用tostring
meta = {}
meta.__tostring = function(a) return "a" end -- 必须返回一个字符串
a = {}
setmetatable(a, meta)
print(a)
禁止目标的metatable被修改
setmetatable/getmetatable函数也会使用metafield,在这种情况下,可以保护metatables。假定你想保护你的集合使其使用者既看不到也不能修改metatables。如果你对metatable设置了__metatable的值,getmetatable将返回这个域的值,而调用setmetatable 将会出错:
meta = { __metatable = "not your business" }
a = {}
setmetatable(a, meta) -- ok & metatable protected
print(getmetatable(a)) -- not your business
setmetatable(a, {}) -- error!!!
输出如下:
not your business
lua: .\a.lua:5: cannot change a protected metatable