2

次のように:演算子を使用してlua関数を宣言するとします。

function ClassName:myFunc( stuff )
    --do stuff
end

そして、その関数を次のようなテーブルに格納するとします。

someTable = {
    ClassName.myFunc,
    someGlobalFunc,
} 

次に、テーブルを調べて指定された関数を呼び出そうとする別の関数があるとします。

function ClassName:callStuffInThisTable(table)
    -- I go through the table, which might be someTable above, and call all the functions
end

私の質問は、テーブル内の関数がClassNameによって所有されているかどうかを確認して、自分自身を使用して呼び出すことができるようにする方法です。

4

2 に答える 2

7

あなたはそうしない。少なくとも、Luaはあなたに話すつもりはありません。

function ClassName:myFunc( stuff )Luaに関する限り、これは単なる構文糖衣です。これと違いはありません:ClassName.myFunc = function (self, stuff)。機能は同等です。同様に、:call構文の場合、ClassName:myFunc(stuff)意味的にはと同等ClassName.myFunc(ClassName, stuff)です。

あなたの機能が何であるか、そしてそれらが何をするかを知るのはあなた次第です。これにはコーディングの規律が必要です。ループで呼び出す必要のある関数のリストがある場合は、同じパラメーターで呼び出すように設計する必要があります。

これを行うには2つの方法があります。1つの方法は、すべての関数を「クラス関数」にすることです。

someTable = {
    ClassName.myFunc,
    function(self, ...) return someGlobalFunc(...) end,
} 

このように、selfパラメーターは無視されます。明らかに、ラッパーを自動的に生成する「グローバル」関数をテーブルに挿入するための関数を持つ特別な関数テーブルオブジェクトを作成できます。

function insertFuncIntoTable(self, func)
  self[#self + 1] = function(self, ...) func(...) end
end

insertFuncIntoTable(someTable, someGlobalFunc)

注:「someGlobalFunc」が実際には(ではなく)グローバルテーブルのメンバーであると仮定すると、これらには違いがありますlocal。このバージョンは、元のコードと同じように、_G["someGlobalFunc"] 現在の値を取ります。ただし、最初のバージョンは、呼び出されたときの値を取ります。これは、作成されたときの関数とは異なる可能性がありますsomeTable

したがって、このバージョンの方が安全です。

または、テーブル内の「クラス関数」がオブジェクトインスタンスに明示的にバインドされるようにすることもできます。

someTable = {
    function(self, ...) ClassName.myFunc() end,
    function(self, ...) return someGlobalFunc(...) end,
} 

ところで、一般的に、:構文を使用して関数を宣言する場合は、を介してその関数をそのように使用するinstance:myFunc(...)ことになっています。明らかに、それは他の関数と同じように単なるLua関数なので、好きなことを行うことができます。しかし、誤用は何が起こっているのかを理解するのを難しくする可能性があります。

Luaはあなたにたくさんの力を与えます。ただし、コーディングするときは、判断と規律を行使する必要があります。Luaはあなたをあなた自身から(完全に)救うことはありません。

于 2012-04-04T23:36:23.997 に答える
0

関数がClassNameによって「所有」されているかどうかを確認する方法のひとつは、スキャンして確認することです。

ClassName = {}
function ClassName:fn(self) ... end

t = { function() ... end , ClassName.fn() }

function has_value( klass, value )
  for k,v in pairs(klass) do
    if v==value then return true
  end
  return false

function ClassName:callStuffInThisTable(table)
  for k,v in pairs(table) do
    if has_value(ClassName, v) then
      v(self)
    else
      v()
    end
  end
end

これは、テーブルスキャンによるものですが、O(n ^ 2)の動作をします。ClassNameの関数を新しいテーブルとして使用することで、これをO(n log(n)))に減らすことができます。

function ClassName:callStuffInThisTable(table)
  local t = {}
  for k,v in pairs(ClassName) do
    t[v] = 1
  end

  for k,v in pairs(table) do
    if t[v]==1 then
      v(self)
    else
      v()
    end
  end
end   
于 2012-04-05T01:16:56.530 に答える