5

前に、メタテーブルのメソッドが Lua によって検索されない理由を尋ねたところ、メタテーブルに設定__indexすることで問題が解決すると言われました。しかし、インデックスブラケット[]メタ__indexテーブルを使用する必要があるため、その中のテーブルからインデックスを返すように割り当てられているため、メソッドを使用して両方の機能のニーズを解決するにはどうすればよいですか?割り出しブラケット

問題を示す最小限の例を書きました。

TestMetatable = {DataTable = {}}
TestMetatable.__index = TestMetatable

function TestMetatable.new()
    local Tmp = {}
    setmetatable(Tmp,TestMetatable)

    Tmp.DataTable = {1}

    return Tmp
end

function TestMetatable:TestMethod()
    print("Ran Successfully")
end

function TestMetatable.__index(self,index)
    return self.DataTable[index]
end

local Test = TestMetatable.new()

-- both functionalities are needed
print(Test[1])
Test:TestMethod()
4

2 に答える 2

8

と の違い、__indexおよびメイン テーブルの現在の__newindex内容との関係を理解する必要があります。

__newindex次のすべてが true の場合にのみ、呼び出されたりアクセスされたりします。

  • tbl[index] = expr(または のような同等の構文)を介して、メイン テーブルに値を設定する場合tbl.name = expr
  • メイン テーブルに設定しようとしているキーがメイン テーブルに存在しない場合

2番目のものは、人々を頻繁につまずかせます。__indexは次の場合にのみアクセスされるため、ここで問題になります。

  • メイン テーブルから読み取られているキーがメイン テーブルにまだ存在しない場合

したがって、テーブルからのすべての読み取りとテーブルへの書き込みをフィルター処理する場合、そのテーブルは常に空でなければなりません。したがって、これらの読み取りと書き込みは、新しいオブジェクトごとに作成する他のテーブルに移動する必要があります。したがって、new関数は 2 つのテーブルを作成する必要があります。1 つは空のままで、もう 1 つはすべてのデータが含まれています。

正直なところ、これらの問題を回避するために、ユーザー定義のメタテーブルをバインドできる空のユーザーデータを作成する方法が Lua にあればいいのにと思います。

于 2013-08-02T21:48:01.297 に答える
0

ニコル・ボーラスの解決策によると、私がこの問題を解決した方法は、他の誰かの混乱を明確にするかもしれません:-)

TestMetatable = {DataTable = {}, FunctionTable = {}}

function TestMetatable.new()
    local Tmp = {}
    setmetatable(Tmp,TestMetatable)

    Tmp.DataTable = {1}
    Tmp.FunctionTable = TestMetatable

    return Tmp
end

function TestMetatable:TestMethod()
    print("Ran Successfully")
end

function TestMetatable.__index(self,index)
    if type(index) == "string" then
        return self.FunctionTable[index]
    else
        return self.DataTable[index]
    end
end

local Test = TestMetatable.new()

-- both functionalities are needed
print(Test[1])
Test:TestMethod()
于 2013-08-02T22:54:34.430 に答える