メタテーブル
メタテーブルは、言語の一般的な操作をオーバーロードするために使用されます。これらの操作には、加算、乗算、等価比較、および (名前が示すように) キーを介して値にアクセスするなどの表のような操作が含まれますtable[key]
。
メタテーブルは、Lua でオブジェクト指向プログラミングを実装するためによく使用されます。これを駆動する主なメカニズムは、 の使用です__index
。この例は、これを最も基本的な形式で示しています。
>>> parent = {parentID = 'Secret'}
>>> child = {}
>>> setmetatable(child,{__index=parent})
>>> =child.parentID
Secret
キーparentID
は子内に実際には存在しないため、子のどこにも次のようなものはありません。
child = {
parentID = 'Secret'
}
代わりに、誰かが 内に存在しないキーを探すときにchild
、 に移動して調べるようにしました。これは、テーブル に割り当てたメタparent
テーブルに設定されています。
>>> setmetatable(child,{__index=parent})
したがって、プログラムで要求するときのイベントの流れchild.parentID
は次のとおりです。
child
キーが であるキーと値のペアが含まれていますか"parentID"
? いいえ、したがって 2 に進みます。
- メタテーブルで定義されています
child
か? __index
はい、3へ。
- によって参照されるテーブル
__index
を調べて、キーを確認します"parentID"
- 親に発見!の値を返す
parent["parentID"]
これにより、テーブル間の関係を作成できます。__index
次のようなメタテーブル メソッドを使用して、すべてのプレイヤーの情報を表すテーブルと各プレイヤー自身との間の関係を作成できます。
Player = { }
Player_metatable = {
__index = Player --look for the missing key in the Player table
}
function Player.new(name)
aPlayer = { name = name }
setmetatable(aPlayer,Player_metatable)
return aPlayer
end
function Player:rotate()
print("I'M ROTATING",tostring(self))
end
henry = Player.new("Henry")
henry:rotate()
を呼び出すと、最初の例でメタテーブルを設定するのと同じようPlayer.new("Henry")
に、テーブルを作成し、そのメタテーブルを に設定します。ただし、すぐに実行するのではなく、関数内で実行しているだけなので、違いはありません!Player_metatable
child
を呼び出すとhenry:rotate()
、上で概説したように次のようになります: でキーを探します"rotate"
がhenry
、何も見つからないので調べますPlayer
(これがメタテーブルで__index
指し示すテーブルであるため)。そのキーに関連付けられた関数があります。そのため、その関数を呼び出して、t:function
構文のために自分自身を渡します。
クラスのインスタンスを作成するには、クラスの動作を定義したテーブルを指すメタテーブルであるテーブルを割り当てるだけです。したがって、次のようにして、必要な数の Player を作成できます。
my_player_name = Player.new(...)
テーブルの値を変更するPlayer
と、関連付けられたメタテーブルを持つすべてのテーブルに反映されます。