Lua Metatable
3296 ワード
オペランド演算と論理演算(オペレータリロードなど)
ライブラリ定義のメタメソッド
tableアクセスのメタメソッド_indexアクセスtableにフィールドが存在せず、存在する場合_indexのメタメソッド、では呼び出し_index[_index(table,key)]はrawget(table,key)法を用いてこのメカニズムを迂回することができる
__newindex更新されたフィールドがtableに存在せず、存在する場合_newindexメタメソッドでは、__が呼び出されます.newindexメソッド[_newindex(table,key,value)]rawset(table,key,value)メソッドを使用してこのメカニズムを迂回することができる
プロキシアクセスの適用
get/setの簡単な実装
readOnly
弱アプリケーションとゴミ回収Luaにおけるtableの弱リファレンスには3種類のKey弱リファレンスがあり、Value弱アプリケーション、Key、Valueは同時に弱リファレンス対応文字列であり、それ自体が値であり、対象ではなく、必ずしも回収されるとは限らない.
弱い参照を定義_modeメタフィールド
+-*/ __add __sub __mul __div
% ^ __mod,__pow
== < > __eq __lt __le
local obj = {1}
m = getmetatable(obj)
print m -- nil
m = {__add = function(a,b) return {a,b} end}
setmetatable(obj,m)
local obj2 = {2}
setmetatable(obj2,m)
local ret = obj +_ obj2 -- {{1},{2}}
ライブラリ定義のメタメソッド
__tostring
local a = {}
local mt = {__tostring = function(t) return "table_a" end}
setmetatable(a,mt)
print() -- print(tostring(a)) == __tostring(a) table_a
__metatable: ,getmetatable ,
setmetatble
tableアクセスのメタメソッド_indexアクセスtableにフィールドが存在せず、存在する場合_indexのメタメソッド、では呼び出し_index[_index(table,key)]はrawget(table,key)法を用いてこのメカニズムを迂回することができる
local obj = {name="obj"}
local mt = {
__index = function(t,k) return "test" end
}
setmetatable(obj,mt)
-- any not exists key in obj will return test
print(obj.name) -- "obj"
print(obj.any) -- "test"
__newindex更新されたフィールドがtableに存在せず、存在する場合_newindexメタメソッドでは、__が呼び出されます.newindexメソッド[_newindex(table,key,value)]rawset(table,key,value)メソッドを使用してこのメカニズムを迂回することができる
obj = {name="obj"}
mt = {
-- we cannot use t[k]=v this will recursive invoke __newindex
__newindex = function(t,k,v) v = "test_"..tostring(v) rawset(t,k,v) end
}
setmetatable(obj,mt)
print(obj.name) -- "obj"
obj.name = "hello" print(obj.name) -- "hello"
obj.any = "work" print(obj.any) -- "test_work"
obj.any = "any" print(obj.any) -- "any" because any is exists in table
プロキシアクセスの適用
function create_proxy(target)
local _t = target
local t = {}
local mt = {
__index = function(t,k) print("access to element "..tostring(k)) return _t[k] end,
__newindex = function(t,k,v) print("update element "..tostring(k)) _t[k] = v end
}
setmetatable(t,mt)
return t;
end
target = {}
proxy = create_proxy(target)
proxy.price = 10.0
print(proxy.price)
get/setの簡単な実装
local Book = {}
function Book.new()
local accessor = {
name = {
value = 0,
get = function() return value end,
set = function(new_value) value = new_value end
}
}
local meta = {
__index = function(_,key)
return accessor[key].get();
end,
__newindex = function(_,key,value)
accessor[key].set(value)
end
}
local o = {}
setmetatable(o,meta);
return o
end
local mybook = Book.new()
mybook.name = "bookname_100"
print(mybook.name)
readOnly
function readOnly(t)
local proxy = {}
local mt = {
__index = t,
__newindex = function(t,k,v) error("attempt to update a readonly table",2) end
}
setmetatable(proxy,mt)
return proxy
end
弱アプリケーションとゴミ回収Luaにおけるtableの弱リファレンスには3種類のKey弱リファレンスがあり、Value弱アプリケーション、Key、Valueは同時に弱リファレンス対応文字列であり、それ自体が値であり、対象ではなく、必ずしも回収されるとは限らない.
弱い参照を定義_modeメタフィールド
a = {}
mt = {__mode = "k"}
setmetatable(a,mt) -- a key
key = {}
a[key] = 1
key={} //pre key is nil,will be collected as garbage
a[key] = 2
collectgarbage()
for k,v in pairs(a) do print(v) end -->2