Lua-metatables

提供:Dev Guides
移動先:案内検索

Lua-メタテーブル

メタテーブルは、キーセットおよび関連するメタメソッドの助けを借りて、アタッチされているテーブルの動作を変更するのに役立つテーブルです。 これらのメタメソッドは、次のような機能を有効にする強力なLua機能です-

  • テーブルの演算子への機能の変更/追加。
  • メタテーブルで__indexを使用して、キーがテーブルで使用できないときにメタテーブルを検索します。

以下を含むメタテーブルの処理に使用される2つの重要な方法があります-

  • * setmetatable(table、metatable)*-このメソッドは、テーブルのメタテーブルを設定するために使用されます。
  • * getmetatable(table)*-このメソッドは、テーブルのメタテーブルを取得するために使用されます。

最初に、あるテーブルを別のテーブルのメタテーブルとして設定する方法を見てみましょう。 以下に示します。

mytable = {}
mymetatable = {}
setmetatable(mytable,mymetatable)

上記のコードは、次のように1行で表すことができます。

mytable = setmetatable({},{})

_index

メタテーブルがテーブルで利用できない場合にメタテーブルを検索するためのメタテーブルの簡単な例を以下に示します。

mytable = setmetatable({key1 = "value1"}, {
   __index = function(mytable, key)

      if key == "key2" then
         return "metatablevalue"
      else
         return mytable[key]
      end
   end
})

print(mytable.key1,mytable.key2)

上記のプログラムを実行すると、次の出力が得られます。

value1 metatablevalue

上記の例で何が起こったのかを段階的に説明しましょう。

  • ここのテーブルmytableは \ {key1 = "value1"} です。
  • メタテーブルは、メタメソッドとして呼び出す__indexの関数を含むmytableに設定されます。 *メタメソッドは、インデックス "key2"を検索するという単純な作業を行い、見つかった場合は "metatablevalue"を返し、そうでない場合は対応するインデックスのmytableの値を返します。

以下に示すように、上記のプログラムの簡易バージョンを作成できます。

mytable = setmetatable({key1 = "value1"},
   { __index = { key2 = "metatablevalue" } })
print(mytable.key1,mytable.key2)

__newindex

__newindexをメタテーブルに追加するときに、テーブルでキーが使用できない場合、新しいキーの動作はメタメソッドによって定義されます。 メインテーブルでインデックスが使用できない場合にメタテーブルのインデックスが設定される簡単な例を以下に示します。

mymetatable = {}
mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })

print(mytable.key1)

mytable.newkey = "new value 2"
print(mytable.newkey,mymetatable.newkey)

mytable.key1 = "new  value 1"
print(mytable.key1,mymetatable.newkey1)

上記のプログラムを実行すると、次の出力が得られます。

value1
nil new value 2
new  value 1    nil

上記のプログラムを見るとわかるように、メインテーブルにキーが存在する場合は更新されます。 キーがメインテーブルで使用できない場合、そのキーをメタテーブルに追加します。

rawset関数を使用して同じテーブルを更新する別の例を以下に示します。

mytable = setmetatable({key1 = "value1"}, {

   __newindex = function(mytable, key, value)
      rawset(mytable, key, "\""..value.."\"")
   end
})

mytable.key1 = "new value"
mytable.key2 = 4

print(mytable.key1,mytable.key2)

上記のプログラムを実行すると、次の出力が得られます。

new value   "4"

rawsetは、メタテーブルのnewindexを使用せずに値を設定します。 同様に、 indexを使用せずに値を取得するrawgetがあります。

テーブルへのオペレーターの動作の追加

+を使用して2つのテーブルを結合する簡単な例演算子は以下に示されています-

mytable = setmetatable({ 1, 2, 3 }, {
   __add = function(mytable, newtable)

      for i = 1, table.maxn(newtable) do
         table.insert(mytable, table.maxn(mytable)+1,newtable[i])
      end
      return mytable
   end
})

secondtable = {4,5,6}

mytable = mytable + secondtable

for k,v in ipairs(mytable) do
   print(k,v)
end

上記のプログラムを実行すると、次の出力が得られます。

1   1
2   2
3   3
4   4
5   5
6   6

演算子+の動作を追加するために、__ addキーがメタテーブルに含まれています。 キーと対応する演算子の表を以下に示します。

Sr.No. Mode & Description
1
  • __add*

演算子「+」の動作を変更します。

2

__sub

演算子「-」の動作を変更します。

3

__mul

演算子「*」の動作を変更します。

4

__div

演算子「/」の動作を変更します。

5

__mod

演算子 '%'の動作を変更します。

6

__unm

演算子「-」の動作を変更します。

7

__concat

演算子「..」の動作を変更します。

8

__eq

演算子「==」の動作を変更します。

9

__lt

演算子「<」の動作を変更します。

10

__le

演算子「⇐」の動作を変更します。

__コール

メソッド呼び出しの動作を追加するには、__ callステートメントを使用します。 メインテーブルの値の合計と、渡されたテーブルを返す簡単な例。

mytable = setmetatable({10}, {
   __call = function(mytable, newtable)
   sum = 0

      for i = 1, table.maxn(mytable) do
         sum = sum + mytable[i]
      end

      for i = 1, table.maxn(newtable) do
         sum = sum + newtable[i]
      end

      return sum
   end
})

newtable = {10,20,30}
print(mytable(newtable))

上記のプログラムを実行すると、次の出力が得られます。

70

__tostring

printステートメントの動作を変更するには、__ tostringメタメソッドを使用できます。 以下に簡単な例を示します。

mytable = setmetatable({ 10, 20, 30 }, {
   __tostring = function(mytable)
   sum = 0

      for k, v in pairs(mytable) do
         sum = sum + v
      end

      return "The sum of values in the table is " .. sum
   end
})
print(mytable)

上記のプログラムを実行すると、次の出力が得られます。

The sum of values in the table is 60

メタテーブルの機能を完全に理解している場合は、使用しなくても非常に複雑な多くの操作を実際に実行できます。 そのため、サンプルで説明されているように、メタテーブルで使用可能なさまざまなオプションを使用してメタテーブルを使用し、独自のサンプルを作成してください。