2011-05-20 112 views

回答

29

Lua是一種動態語言,函數只是一種可以用()運算符調用的值。所以你不需要轉發聲明這個函數,因爲當你調用它時,確保變量的範圍是你認爲它的變量。

這對於包含函數的全局變量來說根本不是問題,因爲全局環境是查找來解析變量名稱的默認位置。然而,對於本地函數,您需要確保局部變量已經在您需要調用其存儲的值的詞彙點範圍內,並且還要確保在運行時它確實擁有一個可以調用的值。

例如,這裏是一對相互遞歸局部函數:

local a,b 
a = function() return b() end 
b = function() return a() end 

當然,同樣使用尾部的例子呼叫,以允許無限循環,什麼也不做,但這裏的要點是聲明。通過在其中存儲函數之前聲明變量local,這些名稱就是本示例其餘部分的詞彙範圍中的局部變量。然後存儲兩個函數,每個函數都指向另一個變量。

+1

好的,謝謝。我設法自己解決,但這個答案仍然有用。 – 2011-05-20 06:17:48

9

您可以轉發通過聲明實際的函數體前宣佈它的名字聲明函數:

local func1 
local func2 = function() 
    func1() 
end 
func1 = function() 
    --do something 
end 

但是期待與本地範圍內聲明函數聲明時纔有必要。這通常是你想要做什麼,但Lua中也支持更多的像C語法,在這種情況下,向前聲明是沒有必要的:

function func2() 
    func1() 
end 
function func1() 
    --do something 
end 
+4

其實,你的第一個例子不會做你認爲它做的事情,因爲第二個'local func1'聲明瞭這個名字的一個* new *變量,並且留下了第一個'func1'孤兒,並且仍然被設置爲'nil'。 – RBerteig 2011-05-20 20:45:03

+0

oops好點,我會解決這個問題 – jhocking 2011-05-20 21:02:45

+1

你的第二個例子也不好,因爲從下面的func1天真地調用「func2」會起作用,但不是因爲任何類型的「前向聲明」。相反,func1是在全局環境(_G)中聲明的,當func2查找func1時,它會檢查_G。這意味着func1在func2運行之前被聲明,因此當它檢查_G時,它可以工作。定義func2後立即拋出func2調用會導致錯誤...因爲func1未被聲明/定義。 – LuaWeaver 2014-07-31 04:14:01

0

在FreeSWITCH中嵌入LUA下測試,提前聲明不工作:

fmsg("CRIT", "It worked.") 
function fmsg(infotype, msg) 
    freeswitch.consoleLog(infotype, msg .. "\n") 
end 

結果:

[ERR] mod_lua.cpp:203 /usr/local/freeswitch/scripts/foo.lua:1:試圖調用全局 'fmsg'(一個零值)

反轉訂單確實(杜)工作。

0

如果我在定義之前嘗試調用該函數,則不適用於我。我在nginx conf中使用這個Lua腳本。

lua entry thread aborted: runtime error: lua_redirect.lua:109: attempt to call global 'throwErrorIfAny' (a nil value)

代碼片段 -

... 
throwErrorIfAny() 
... 

function throwErrorIfAny() 
    ngx.say("request not allowed") 
    ngx.exit(ngx.HTTP_OK) 
end 

考慮一些其他的答案也指出,它沒有爲他們工作,要麼,它是可能的Lua中的前聲明不與其他工具的工作。

PS:它能正常工作,如果我把之前的功能定義,然後在病房後調用它。