前方LUAの関数を定義しますか?
-
06-09-2020 - |
質問
その作成上から呼び出す必要がある関数を呼び出す方法私は前方宣言について何かを読みましたが、Googleはこの場合に役立ちません。これの正しい構文は何ですか?
解決
LUAは動的言語であり、関数は()
演算子で呼び出すことができる一種の値です。それで、あなたがそれを呼び出すとあなたがそれがあると思う変数の変数であることを確認してください。
これは、グローバル環境が変数名を解決するためのデフォルトの場所であるため、関数を含むグローバル変数の問題ではありません。ただし、ローカル関数の場合、ローカル変数が保存されている値を呼び出す必要がある字句ポイントですでにスコープになっていることを確認する必要があります。また、実行時に呼び出すことができる値を実際に保持していることを確認してください。 。
例えば、ここでは、互いに再帰的な局所機能のペアがあります。
local a,b
a = function() return b() end
b = function() return a() end
.
もちろん、無限の再帰を許可するためのテールコールを使用する例も、ここでのポイントは宣言です。 local
を使用して変数を宣言することによって、その名前の関数がある場合、それらの名前は例の残りの字句範囲内のローカル変数であることがわかります。その後、2つの機能が保存され、それぞれが他の変数を参照します。 他のヒント
実際の関数本体を宣言する前にその名前を宣言することで機能を宣言することができます。
local func1
local func2 = function()
func1()
end
func1 = function()
--do something
end
.
しかし、宣言は、ローカルスコープを持つ関数を宣言するときにのみ必要です。それは一般的にあなたがやりたいことですが、LuaはCのような構文をサポートしています。その場合、前方宣言は必要ありません:
function func2()
func1()
end
function func1()
--do something
end
. Freeswitchの組み込みLUAの下でのテスト、前方宣言は機能しません:
fmsg("CRIT", "It worked.")
function fmsg(infotype, msg)
freeswitch.consoleLog(infotype, msg .. "\n")
end
.
結果:
[err] mod_lua.cpp:203/usr/Local/FreeesWitch/Scripts/Foo.lua:1:Global 'FMSG'(NIL値)を呼び出しようとしました
注文を逆転させる(DUH)作業
LUAの順方向参照をCと比較して、CコンパイルとLUAの実行の基本的な違いを理解する必要があります。
-
cでは、前方参照はコンパイル時メカニズムです。したがって、Cモジュールに転送宣言テンプレートを含めると、コードのいずれかのコードのいずれかがこのテンプレートを採用します。同じモジュール内の関数実装を含めることもできない場合があります。この場合、両方の宣言は意味的に同じであるか、またはコンパイラがエラーになる必要があります。これはコンパイル時の構造であるため、コンパイル済みコードは任意の順序で実行できます。
-
LUAでは、フォワード参照は runtime メカニズムです。コンパイルされた関数はコード内で内部的に関数プロトタイプを生成しますが、これはランタイムLUA変数またはその後の値としてのみアクセス可能です。実行施設 宣言を渡したLUA Closure を作成します。ここでは、ソース内の宣言順序は重要ではありません。重要な実行順序です。クロージャがまだ変数にバインドされていない場合、実行は "NIL値"例外をスローします。
ローカルを使用している場合関数値を保持するための変数では、通常のローカルスコープ規則はまだ適用されます.local
宣言は、ソース内でその使用に先行しており、範囲内でなければならないため、コンパイラは間違ったグローバルリファレンスまたは外部のリファレンスでコンパイルされます。そのため、他の回答で説明されているように、ローカルを使用した前方参照は機能します。
定義の前に関数を呼び出しようとすると私のためには機能しません。私はnginx confのこのLUAスクリプトを使っています。
LUAエントリスレッドが中止されました:ランタイムエラー:LUA_REDIRECT.LUA:109:グローバル 'ThrowerRorerifany'(NIL値)
のコールを試みます。
コードスニペット -
...
throwErrorIfAny()
...
function throwErrorIfAny()
ngx.say("request not allowed")
ngx.exit(ngx.HTTP_OK)
end
.
他の答えもまた彼らのためにうまくいかなかったことを指摘しています、LUAの前方宣言は他のツールとは機能しない可能性があります。
PS:区の後に機能定義を入れてから、それを呼び出されたらうまく機能します。
OOPを使用する場合は、その「定義」以前の機能メンバーを呼び出すことができます。
local myClass = {}
local myClass_mt = { __index = myClass }
local function f1 (self)
print("f1")
self:later() --not yet "delared" local function
end
local function f2 (self)
print("f2")
self:later() --not yet "declared" local function
end
--...
--later in your source declare the "later" function:
local function later (self)
print("later")
end
function myClass.new() -- constructor
local this = {}
this = {
f1 = f1,
f2 = f2,
later = later, --you can access the "later" function through "self"
}
setmetatable(this, myClass_mt)
return this
end
local instance = myClass.new()
instance:f1()
instance:f2()
.
プログラム出力:
f1
later
f2
later
.