luaメタテーブルの詳細
12419 ワード
https://www.cnblogs.com/blueberryzzz/p/8947446.html
メタテーブルの役割
メタテーブルはtableまたはuserdataの操作方法を定義するためのテーブルです.
例を挙げる
私たちは直接2つのtableに対して+演算を実行して、間違いを報告します
プログラムは2つのテーブルに対して+実行をどのように実行するか分からないため、この場合、t 1の+演算をどのように実行するかをメタテーブルで定義する必要があり、c言語の演算子の再ロードに似ている.
結果:
プログラムはt 1+t 2を実行すると、t 1のメタテーブルmtの__を呼び出すからであるaddメタメソッドで計算します.具体的な過程は:1.t 1にメタテーブルがあるかどうかを確認し、ある場合はt 1のメタテーブルに__があるかどうかを確認するaddメタメソッド、あれば呼び出します.2.t 2にメタテーブルがあるかどうかを確認し、ある場合はt 2のメタテーブルに__があるかどうかを確認するaddメタメソッド、あれば呼び出します.[原句]なければ間違いを報告する.したがって、t 1メタテーブルの__を定義することによってaddメタメソッドは,2つのテーブルを+番号で加算する効果を達成した.
メタテーブルのメタメソッド
関数#カンスウ#
説明
__add
演算子+
__sub
演算子-
__mul
演算子*
__ div
演算子/
__mod
演算子%
__unm
演算子-(逆)
__concat
演算子..
__eq
演算子==
__lt
演算子<
__le
演算子<=
__call
関数呼び出し時
__tostring
文字列に変換
__index
インデックスを呼び出す
__newindex
インデックスに値を割り当てる
それらの演算子は似ているので、単独では説明しません.call, __tostring, __index, __newindexの4つのメタメソッド.
__call
__callはtableを関数として使用することができます.
結果:
__tostring
__tostringはtableを文字列に変換する動作を変更できます
結果:
__index
tableの存在しないインデックスを呼び出すと、メタテーブルの__が使用されます.indexメタメソッドは、前のメタメソッドとは異なり、_indexは関数でもtableでもよい.関数として:テーブルとインデックスをパラメータとして入力_indexメタメソッド、return戻り値
結果:
tableとして:検索_indexメタメソッドテーブル、インデックスがある場合はインデックスに対応する値を返し、そうでない場合はnilを返します.
結果:
__newindex
tableに存在しないインデックスに値を割り当てると、メタテーブルの__が呼び出されます.newindexメタメソッドを関数として_newindexは関数の場合、付与文のテーブル、インデックス、付与された値をパラメータとして呼び出します.表を変えない
結果:
table_としてnewindexがtableの場合、tに存在しないインデックスに値を割り当てると、インデックスと値が__に割り当てられます.newindexが指すテーブルでは、元のテーブルは変更されません.
結果:
rawgetとrawset
テーブルの値を直接変更したり取得したりするには、rawgetメソッドとrawsetメソッドが必要になる場合があります.rawgetでは、メタテーブルの__ではなく、テーブル内のインデックスの実際の値を直接取得できます.indexメタメソッド.
結果:
rawsetでは、メタテーブルの__ではなく、テーブル内のインデックスに直接値を割り当てることができます.newindexメタメソッド.
結果:
メタテーブルの使用シーン
tableとしてのメタテーブル
tableにメタテーブルを設定することでluaでオブジェクト向けプログラミングを実現できます.
userdataのメタテーブルとして
userdataとメタテーブルによりluaにおけるc中の構造へのオブジェクト向けアクセスを実現できる.
ラベル:lua
メタテーブルの役割
メタテーブルはtableまたはuserdataの操作方法を定義するためのテーブルです.
例を挙げる
local t1 = {1}
local t2 = {2}
local t3 = t1 + t2
私たちは直接2つのtableに対して+演算を実行して、間違いを報告します
lua: /usercode/file.lua:3: attempt to perform arithmetic on local 't1' (a table value)
プログラムは2つのテーブルに対して+実行をどのように実行するか分からないため、この場合、t 1の+演算をどのように実行するかをメタテーブルで定義する必要があり、c言語の演算子の再ロードに似ている.
local mt = {}
-- mt.__add ( )
mt.__add = function(t1,t2) local temp = {} for _,v in pairs(t1) do table.insert(temp,v) end for _,v in pairs(t2) do table.insert(temp,v) end return temp end local t1 = {1,2,3} local t2 = {2} -- t1 mt setmetatable(t1,mt) local t3 = t1 + t2 -- t3 local st = "{" for _,v in pairs(t3) do st = st..v..", " end st = st.."}" print(st)
結果:
{1, 2, 3, 2, }
プログラムはt 1+t 2を実行すると、t 1のメタテーブルmtの__を呼び出すからであるaddメタメソッドで計算します.具体的な過程は:1.t 1にメタテーブルがあるかどうかを確認し、ある場合はt 1のメタテーブルに__があるかどうかを確認するaddメタメソッド、あれば呼び出します.2.t 2にメタテーブルがあるかどうかを確認し、ある場合はt 2のメタテーブルに__があるかどうかを確認するaddメタメソッド、あれば呼び出します.[原句]なければ間違いを報告する.したがって、t 1メタテーブルの__を定義することによってaddメタメソッドは,2つのテーブルを+番号で加算する効果を達成した.
メタテーブルのメタメソッド
関数#カンスウ#
説明
__add
演算子+
__sub
演算子-
__mul
演算子*
__ div
演算子/
__mod
演算子%
__unm
演算子-(逆)
__concat
演算子..
__eq
演算子==
__lt
演算子<
__le
演算子<=
__call
関数呼び出し時
__tostring
文字列に変換
__index
インデックスを呼び出す
__newindex
インデックスに値を割り当てる
それらの演算子は似ているので、単独では説明しません.call, __tostring, __index, __newindexの4つのメタメソッド.
__call
__callはtableを関数として使用することができます.
local mt = {}
--__call
mt.__call = function(mytable,...) -- for _,v in ipairs{...} do print(v) end end t = {} setmetatable(t,mt) -- t t(1,2,3)
結果:
1
2
3
__tostring
__tostringはtableを文字列に変換する動作を変更できます
local mt = {}
--
mt.__tostring = function(t) local s = "{" for i,v in ipairs(t) do if i > 1 then s = s..", " end s = s..v end s = s .."}" return s end t = {1,2,3} -- t print(t) -- t mt setmetatable(t,mt) -- t print(t)
結果:
table: 0x14e2050
{1, 2, 3}
__index
tableの存在しないインデックスを呼び出すと、メタテーブルの__が使用されます.indexメタメソッドは、前のメタメソッドとは異なり、_indexは関数でもtableでもよい.関数として:テーブルとインデックスをパラメータとして入力_indexメタメソッド、return戻り値
local mt = {}
-- ,
mt.__index = function(t,key) return "it is "..key end t = {1,2,3} -- key , nil print(t.key) setmetatable(t,mt) -- key , __index , "it is key" print(t.key)
結果:
nil
it is key
tableとして:検索_indexメタメソッドテーブル、インデックスがある場合はインデックスに対応する値を返し、そうでない場合はnilを返します.
local mt = {}
mt.__index = {key = "it is key"}
t = {1,2,3} -- key , nil print(t.key) setmetatable(t,mt) -- , __index key , __index key "it is key" print(t.key) -- , __index , nil print(t.key2)
結果:
nil
it is key
nil
__newindex
tableに存在しないインデックスに値を割り当てると、メタテーブルの__が呼び出されます.newindexメタメソッドを関数として_newindexは関数の場合、付与文のテーブル、インデックス、付与された値をパラメータとして呼び出します.表を変えない
local mt = {}
-- , ,
mt.__newindex = function(t,index,value) print("index is "..index) print("value is "..value) end t = {key = "it is key"} setmetatable(t,mt) -- key print(t.key) -- newKey , __newIndex , t.newKey = 10 -- newKey , , __newIndex , t print(t.newKey)
結果:
it is key
index is newKey
value is 10
nil
table_としてnewindexがtableの場合、tに存在しないインデックスに値を割り当てると、インデックスと値が__に割り当てられます.newindexが指すテーブルでは、元のテーブルは変更されません.
local mt = {}
-- __newindex newTable
local newTable = {}
mt.__newindex = newTable
t = {}
setmetatable(t,mt) print(t.newKey,newTable.newKey) -- t , t __newindex , t , __newindex newTable newKey "it is newKey" t.newKey = "it is newKey" print(t.newKey,newTable.newKey)
結果:
nil nil
nil it is newKey
rawgetとrawset
テーブルの値を直接変更したり取得したりするには、rawgetメソッドとrawsetメソッドが必要になる場合があります.rawgetでは、メタテーブルの__ではなく、テーブル内のインデックスの実際の値を直接取得できます.indexメタメソッド.
local mt = {}
mt.__index = {key = "it is key"}
t = {}
setmetatable(t,mt)
print(t.key) -- rawget t key print(rawget(t,"key"))
結果:
it is key
nil
rawsetでは、メタテーブルの__ではなく、テーブル内のインデックスに直接値を割り当てることができます.newindexメタメソッド.
local mt = {}
local newTable = {}
mt.__newindex = newTable
t = {}
setmetatable(t,mt)
print(t.newKey,newTable.newKey) -- rawset t newKey rawset(t,"newKey","it is newKey") print(t.newKey,newTable.newKey)
結果:
nil nil
it is newKey nil
メタテーブルの使用シーン
tableとしてのメタテーブル
tableにメタテーブルを設定することでluaでオブジェクト向けプログラミングを実現できます.
userdataのメタテーブルとして
userdataとメタテーブルによりluaにおけるc中の構造へのオブジェクト向けアクセスを実現できる.
ラベル:lua