luaメタテーブルとオブジェクト向け
3329 ワード
メタテーブル
まずluaのnumberタイプは、例えば、いくつかの操作を実行することができる.
2つの複素数を以下のように定義すれば,その加算を実現することが望ましい.
この2つの変数を直接加算すると、lua解釈器はエラーを教えてくれます.このとき,メタテーブルによって所望の結果を達成することができ,メタテーブルはメタ操作または挙動の集合として理解できる.任意の変数のメタテーブルは、
式a+bは、Luaでは以下の手順で行われるまず、aとbの両方がメタテーブル を有するか否かを判断する.メタテーブルに__という名前があるかどうかを確認します.addのフィールド;フィールドが見つかった場合は、フィールドに対応する値を呼び出します.この値はメソッドに対応します.
Luaでは、各値に1つのメタテーブルがあり、tableタイプとuserdataタイプの各変数にはそれぞれ独立したメタテーブルがあり、他のタイプの値はそのタイプが属する単一のメタテーブルを共有します.
加算に加えて、メタテーブルには次のような操作があります.
Mode
説明
__add
プラス
__sub
減らす
__mul
乗ずる
__div
を除いて
__mod
余剰を取る
__unm
逆数をとる
__concat
せつぞく
__eq
に等しい
__lt
より小さい
__le
以下
__call
メソッドとしてtableを呼び出すとメタテーブルの__が呼び出されます.call
__tostring
tableをstringとして入力するとメタテーブルの__が呼び出されます.tostring
__index
以下に述べる
__newindex
以下に述べる
__indexメタメソッド
tableのフィールドにアクセスすると、tableにこのフィールドがある場合は、対応する値を直接返します.tableにこのフィールドがない場合、tableのメタテーブルの__を探します.index、nilを返すのが見つかりませんでした.もしあるならば2種類の情況に分けて、_indexは方法でもtableでもよい.
メソッドの場合、tableとkeyがこのメソッドを呼び出し、結果は次のようになります.
tableであれば、このtableに対応するkeyを探し、見つけたら返し、見つからなければこのtableのメタテーブルを探し続ける_.index、つまりずっと上を探しています.
__newindexメタメソッド
この方法はtableのkeyを更新するときに呼び出され,すなわちtableのkeyに値を付与するときである.主な役割は
オブジェクト向け
上のメタテーブルの基礎があればluaのオブジェクト向けを実現できます.オブジェクトを作成するときにメタメソッドの__としてtableをクラスとして定義します.index、luaのselfキーワードを再使用
次は継承
もちろん,クラスとオブジェクトと継承を実現する方法には他にも多くの種類があり,上はその原理を例示しているだけである.クラスを定義し、親クラスに転送し、オブジェクト向けをより容易に実現するためにclassメソッドをカプセル化できます.ここでは詳しくは述べない.関連キーワードを直接検索すればいいです.
まずluaのnumberタイプは、例えば、いくつかの操作を実行することができる.
1 + 1 //2
1 - 1 //0
2つの複素数を以下のように定義すれば,その加算を実現することが望ましい.
local a = {1, 2}
local b = {3, 4}
// {4, 6}
この2つの変数を直接加算すると、lua解釈器はエラーを教えてくれます.このとき,メタテーブルによって所望の結果を達成することができ,メタテーブルはメタ操作または挙動の集合として理解できる.任意の変数のメタテーブルは、
setmetatable
によって設定されたtable
のメタテーブルgetmetatable
によって取得することができる.新しいtableが作成されるとメタテーブルが空になります.式a+bは、Luaでは以下の手順で行われる
Luaでは、各値に1つのメタテーブルがあり、tableタイプとuserdataタイプの各変数にはそれぞれ独立したメタテーブルがあり、他のタイプの値はそのタイプが属する単一のメタテーブルを共有します.
local m = {
__add = function (a, b)
return {a[1] + b[1], a[2] + b[2]}
end
}
local a = setmetatable({1,2}, m)
local b = setmetatable({3,4}, m)
// a + b {4, 6}
加算に加えて、メタテーブルには次のような操作があります.
Mode
説明
__add
プラス
__sub
減らす
__mul
乗ずる
__div
を除いて
__mod
余剰を取る
__unm
逆数をとる
__concat
せつぞく
__eq
に等しい
__lt
より小さい
__le
以下
__call
メソッドとしてtableを呼び出すとメタテーブルの__が呼び出されます.call
__tostring
tableをstringとして入力するとメタテーブルの__が呼び出されます.tostring
__index
以下に述べる
__newindex
以下に述べる
__indexメタメソッド
tableのフィールドにアクセスすると、tableにこのフィールドがある場合は、対応する値を直接返します.tableにこのフィールドがない場合、tableのメタテーブルの__を探します.index、nilを返すのが見つかりませんでした.もしあるならば2種類の情況に分けて、_indexは方法でもtableでもよい.
メソッドの場合、tableとkeyがこのメソッドを呼び出し、結果は次のようになります.
local m = {
__index = function(table, key)
return key .. key
end
}
local t = {}
setmetatable(t, m)
// t.a == 'aa', t.abc == 'abcabc'
tableであれば、このtableに対応するkeyを探し、見つけたら返し、見つからなければこのtableのメタテーブルを探し続ける_.index、つまりずっと上を探しています.
local a = {}
local b = {a = 1}
local c = {b = 2}
setmetatable(a, {__index = b})
setmetatable(b, {__index = c})
// a.a == 1
// a.b == 2
__newindexメタメソッド
この方法はtableのkeyを更新するときに呼び出され,すなわちtableのkeyに値を付与するときである.主な役割は
local a = {}
setmetatable(a, {
__newindex = function(table, key, value)
print(key)
print(value)
end
})
a.a = 10
// a 10
オブジェクト向け
上のメタテーブルの基礎があればluaのオブジェクト向けを実現できます.オブジェクトを作成するときにメタメソッドの__としてtableをクラスとして定義します.index、luaのselfキーワードを再使用
local People = {
name = ''
}
function People:say()
print(self.name)
end
function People:new(name)
local o = {name = name}
setmetatable(o, {__index = self})
return o
end
local xiaoming = People:new('xiaoming')
xiaoming:say() // xiaoming
次は継承
local People = {
name = ''
}
function People:say()
print(self.name)
end
function People:new(name)
local o = {name = name}
setmetatable(o, {__index = self})
return o
end
local Teacher = {
}
function Teacher:say()
print('teacher ' .. self.name)
end
setmetatable(Teacher, {__index = People})
local xiaoming = Teacher:new('xiaoming')
xiaoming:say() // teacher xiaoming
もちろん,クラスとオブジェクトと継承を実現する方法には他にも多くの種類があり,上はその原理を例示しているだけである.クラスを定義し、親クラスに転送し、オブジェクト向けをより容易に実現するためにclassメソッドをカプセル化できます.ここでは詳しくは述べない.関連キーワードを直接検索すればいいです.