Luaノート--メタテーブルとメタメソッド
2848 ワード
メタテーブルを使用して、値の動作を変更し、事前定義されていない操作に直面したときに指定された操作を実行できます.Luaが2つのtableを加算しようとすると、両方のいずれかにメタテーブルがあるかどうかを確認し、元のテーブルに__という名前があるかどうかを確認します.addのフィールド.
Luaは新しいtableを作成するときにメタテーブルを作成しません.setmetatableを使用してtableのメタテーブルを設定または変更できます.
Luaではtableのメタテーブルしか設定できませんが、他のタイプの値のメタテーブルを設定するにはCコードで行う必要があります.その他のタイプは、デフォルトではメタテーブルがありません.
1、算術類のメタメソッド
2、関係類のメタメソッド
3、tableアクセスのメタメソッド
__newindexメタメソッドと_indexメタメソッドは、前者はtableの更新に使用され、後者はtableのクエリーに使用される点で同様である.1つのtableに存在しないインデックスに値を割り当てると、解釈器は__を検索します.newindexメタメソッド.このメタメソッドがある場合、解釈器は割り当てを実行するのではなく、それを呼び出します.
Luaは新しいtableを作成するときにメタテーブルを作成しません.setmetatableを使用してtableのメタテーブルを設定または変更できます.
Luaではtableのメタテーブルしか設定できませんが、他のタイプの値のメタテーブルを設定するにはCコードで行う必要があります.その他のタイプは、デフォルトではメタテーブルがありません.
1、算術類のメタメソッド
Set = {}
local mt = {}
--
function Set.new( l )
local set = {}
setmetatable(set, mt) -- mt table
for _, v in ipairs(l) do set[v] = true end
return set
end
function Set.union( a, b )
local res = Set.new{}
for k in pairs(a) do res[k] = true end
for k in pairs(b) do res[k] = true end
return res
end
function Set.intersection( a, b )
local res = Set.new{}
for k in pairs(a) do res[k] = b[k] end
return res
end
function Set.tostring( set )
local l = {}
for e in pairs(set) do l[#l + 1] = e end
return "{" ..table.concat(l, ", ") .. "}"
--table.concat ,
end
function Set.print( s )
print(Set.tostring(s))
end
s1 = Set.new{1, 2, 3, 4}
s2 = Set.new{2, 5}
--
print(getmetatable(s1)) -->table: 0x7fee11c09940
print(getmetatable(s2)) -->table: 0x7fee11c09940
-- 。
mt.__add = Set.union
-- Lua , Set.union ,
s3 = s1 + s2
Set.print(s3) -->{1, 2, 3, 4, 5}
-- ,
mt.__mul = Set.intersection
Set.print((s1 + s2) * s1) -->{1, 2, 3, 4}
--[[
, 。 __add __mul , __sub( )、
__div( )、__unm( )、__mod( )、__pow( )。 , __concat
, 。
]]
2、関係類のメタメソッド
mt.__le = function ( a, b ) --
for k in pairs(a) do
if not b[k] then return false end
end
return true
end
mt.__lt = function ( a, b )
return a <= b and not (b <= a)
end
mt.__eq = function ( a, b )
return a <= b and b <= a
end
s1 = Set.new{2, 4}
s2 = Set.new{2, 4, 8}
print(s1 <= s2) -->true
print(s1 < s2) -->true
print(s1 >= s2) -->false
print(s1 > s2) -->false
print(s1 == s2 * s1) -->true
3、tableアクセスのメタメソッド
--[[ table , __index 。
, nil, 。
]]
Window = {} --
--
Window.prototype = {x=0, y=0, width=100, height=200}
Window.mt = {} --
--
function Window.new( o )
setmetatable(o, Window.mt)
return o
end
-- __index
Window.mt.__index = function ( table, key )
return Window.prototype[key]
end
--__index , table
--Window.mt.__index = Window.prototype
-- ,
w = Window.new{x = 10, y = 20}
print(w.width) -->100
__newindexメタメソッドと_indexメタメソッドは、前者はtableの更新に使用され、後者はtableのクエリーに使用される点で同様である.1つのtableに存在しないインデックスに値を割り当てると、解釈器は__を検索します.newindexメタメソッド.このメタメソッドがある場合、解釈器は割り当てを実行するのではなく、それを呼び出します.