4

コロナのテーブルとメタテーブルの違いは何ですか?メタテーブルの種類は何ですか?どこでどのように使用できますか?テーブルとメタテーブルを使用する主な目的は何ですか?

4

2 に答える 2

15

Luaのテーブルは、動的な構造化データを作成するために使用できる主なデータ型です。他の言語には配列、リスト、辞書(Key-Valueストレージ)があり、Luaにはテーブルしかありません。基本テーブルで実行できる唯一の操作は、tab[key]構文を使用して値にインデックスを付けて格納することです。

local tab = {}
tab['key1'] = 'Hello' -- storing a value using a string key
tab.key2 = 'World'    -- this is syntax sugar, equivalent to previous
print(tab.key1, tab['key2'])  -- indexing, the syntax is interchangable

基本的なテーブルでは、他に何もできません。たとえば、次のように追加します。

local v1={x=0,y=0}
local v2={x=1,y=1}
print(v1+v2)
--> stdin:1: attempt to perform arithmetic on local 'v1' (a table value)

メタテーブルを使用すると、テーブルの動作を変更したり、テーブルの追加、乗算、連結()などを行うときに何を実行するかを指定できます。メタテーブルは..、メタメソッドとも呼ばれる特別なキーを持つ関数を含む単なるテーブルです。を使用して、メタテーブルをテーブルに割り当てることができますsetmetatable()。例えば:

local Vector = {} -- this will be the metatable for vectors

function Vector.__add(v1, v2) -- what to do when vectors are added
    -- create a new table and assign it a Vector metatable
    return setmetatable({x=v1.x+v2.x, y=v1.y+v2.y}, Vector)
end
function Vector.__tostring(v) -- how a vector should be displayed
    -- this is used by tostring() and print()
    return '{x=' .. v.x .. ',y=' .. v.y .. '}'
end

local v1 = setmetatable({x=1, y=2}, Vector)
local v2 = setmetatable({x=3, y=4}, Vector)

-- vectors are added and the resulting vector is printed
print(v1 + v2) --> {x=4,y=6}

メタテーブルをよりよく理解したい場合は、メタテーブルに関するLuaのプログラミングの章を必ず読んでください

于 2012-06-05T07:25:51.887 に答える
13

Lua(Coronaのベースとなる言語)は、さまざまな目的でメタテーブルを使用します。

マニュアルの関連するエントリはセクション2.8です。素敵なチュートリアルはここまたはここにあります

メタテーブルは他のテーブルと同じですが、別のテーブルでメタテーブルとして設定されます(2つのテーブルを区別するために、これをベーステーブルと呼びます)。

メタテーブルには何でも含めることができますが、特別なキー(二重アンダースコアで始まる)は興味深いものです。このテーブルでこのキーに設定された値は、特別な機会に呼び出されます。どの機会がどのキーに依存します。最も興味深いのは次のとおりです。

  • __index:ベーステーブルのキーが検索されるたびに使用されますが、存在しません。これには、代わりにキーが検索されるテーブル、または元のテーブルとキーが渡される関数のいずれかを含めることができます。これは、テーブルへのメソッドの実装(OOPスタイル)、リダイレクト、フォールスルーケース、デフォルトの設定などに使用できます。
  • __newindex:テーブルに新しいキーが割り当てられる場合は常に使用されます(以前はnilでした)。テーブルの場合、キーはそのテーブルに割り当てられます。関数の場合、その関数には元のテーブル、キー、および値が渡されます。これは、テーブルへのアクセスの制御、データの前処理、割り当てのリダイレクトに使用できます。
  • __call:たとえば、を使用する場合に呼び出される関数を設定できます。table()
  • __add,__sub,__mul,__div,__mod二項演算を実装するために使用され、
  • __unm単項演算を実装するために使用され、
  • __concat連結を実装するために使用されます(..演算子)
  • __len長さ演算子(#)を実装するために使用されます
  • __eq,__lt,__le比較を実装するために使用されます

__index&co。を使用するときに知っておくべき小さなこと:これらのメソッドでは、メタメソッドが毎回呼び出されてループが発生するのを防ぐために、rawgetとrawsetを使用する必要があります。小さな例として:

t={1,2,3}  -- basetable
mt={} -- metatable
mt.__index=function(t,k)
    print("__index event from "..tostring(t).." key "..k)
    return "currently unavailable"
end
mt.__newindex=function(t,k,v)
    print("__newindex event from "..tostring(t).." key: "..k.." value: "..v)
    if type(k)=="string" then
        rawset(t,k,v:reverse())
    else
        rawset(t,k,v)
    end
end
mt.__call=function(t,...)
    print("call to table "..tostring(t).." with arguments: ".. table.concat({...},','))
    print("All elements of the table:")
    for k,v in pairs(t) do print(k,v) end
end
setmetatable(t,mt)

t[4]="foo" -- this will run the __newindex method
print(t[5]) -- this will run the __index method
t("foo","bar")
-- Multiple fall through example:
t={}
mt={}
mt2={}
setmetatable(t,mt)  -- metatable on base table
setmetatable(mt,mt2) -- second layer of metatable
mt.__index=function(t,k) print('key '..k..' not found in '..namelookup[t]) return getmetatable(t)[k] end -- tries looking nonexistant indexes up in mt.
mt2.__index=mt.__index -- function was written portably, reuse it.

t[1]='A'
mt[2]='B'
mt2[3]='C'
namelookup={[t]="t",[mt]="mt",[mt2]="mt2"}
print(t[1],t[2],t[3],t[4])

これらはばかげた例に過ぎませんが、もっと複雑なことを行うことができます。例を見て、Luaでのプログラミングの関連する章を見て、実験してください。そして、混乱しないようにしてください;)

于 2012-06-05T07:59:19.923 に答える