2

何が起こっているのかを十分に理解していないため、この質問に何と名前を付けるべきかわかりませんでした.(自由に編集してください)

以下のコードを検討してください。

関数オブジェクト:new()
    o = o または {
        x = 0
    }
    setmetatable(o, self)
    self.__index = 自己
    自己.y = 0

お返し
終わり

テーブル = オブジェクト:new()

後で変数 (ox と self.y) の違いは何ですか?

変数をprint_r するとtable、x のみが返されます。ただし、 と の両方table.xtable.yアクセスできます。これは、両者の間に違いがあることを認識させてくれます。

誰かが違いを説明できますか?変数を異なる場所に配置する理由は何ですか?

4

1 に答える 1

4

後で変数 (ox と self.y) の違いは何ですか?

ここには 2 つのテーブルがobjectありoます。

object:newself表参照object。テーブルself.y内のフィールドも同様objectです。

oを呼び出すたびに作成する新しいテーブルですobject:newo.xテーブル内のフィールドoです。

そのoテーブルにはエントリが 1 つしかないo["x"]ため、(そうであるように) テーブル内のエントリを反復処理すると、表示さprint_rれるのはそれだけです。

では、なぜ はo.yあなたに値を与えるのでしょうか? テーブルをのメタテーブルobjectとして設定し、そのメタテーブルにはフィールドが設定されているため、 でインデックスの試行が失敗すると、Lua は のメタテーブルを介して再試行します ( __indexが設定されている場合)。o__indexoo

少しコードを書くと、おそらくこれがより明確になります。

o = { x = 33 }

print(o.x, o.y) --> 33 nil

-- let's give o a metatable
mt = { y = 20 }
setmetatable(o, mt)

-- we've given o a metatable, but that metatable doesn't have an __index member set
print(o.y) --> nil

-- metatable `handlers` are normally functions that handle events
-- here we create a handler for indexing a table if the key doesn't exist in the table:
mt.__index = function(t,k)
  print("An attempt was made to index table", t, "with the key", k)
  return 5150
end

-- we've given o's metatable a handler for indexing which always returns 5150
print(o.x) --> 33
print(o.y) --> 5150
print(o.z) --> 5150
print(o.donut) --> 5150

-- note that Lua has a "rawget" function, which bypasses the metatable mechanics
print(rawget(o,'x')) --> 33, we get a value, because o actually contains "x"
print(rawget(o,'y')) --> nil, back to nil, because the metatable is being ignored

-- the __index metatable handler is special. Instead of providing a function
-- to handle missing key events, you can give it a table. If an index attempt fails,
-- it will try again in the __index table
mt.__index = mt -- we could have used a third table here, but mt has the y entry we want

-- we've changed the metatable handler, so now we'll get 777
print(o.y) --> 777

-- changes to the metatable are reflected in any object using it as metatable
mt.__index.y = 999
print(o.y) --> 999

-- now we give `o` it's OWN "y" entry, so the metatable handler will no longer be invoked
o.y = 2112

print(o.y) --> 2112
print(rawget(o, 'y')) --> o really owns this "y" entry
print(mt.__index.y) --> 999, the metatable was untouched by our write to o.y
于 2012-05-19T22:45:35.793 に答える